Mac: Fix performance issues with remote CoreAnimation
[chromium-blink-merge.git] / sync / syncable / model_type.cc
blob5b92c786fc4d2f290387629155bbb0dbed72d189
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 COMPILE_ASSERT(
47 33 == MODEL_TYPE_COUNT,
48 update_kUserSelectableDataTypeNames_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 ARTICLES:
142 specifics->mutable_article();
143 break;
144 case WIFI_CREDENTIALS:
145 specifics->mutable_wifi_credential();
146 break;
147 default:
148 NOTREACHED() << "No known extension for model type.";
152 ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) {
153 ModelTypeSet protocol_types = ProtocolTypes();
154 for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good();
155 iter.Inc()) {
156 if (GetSpecificsFieldNumberFromModelType(iter.Get()) == field_number)
157 return iter.Get();
159 return UNSPECIFIED;
162 int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
163 DCHECK(ProtocolTypes().Has(model_type))
164 << "Only protocol types have field values.";
165 switch (model_type) {
166 case BOOKMARKS:
167 return sync_pb::EntitySpecifics::kBookmarkFieldNumber;
168 case PASSWORDS:
169 return sync_pb::EntitySpecifics::kPasswordFieldNumber;
170 case PREFERENCES:
171 return sync_pb::EntitySpecifics::kPreferenceFieldNumber;
172 case AUTOFILL:
173 return sync_pb::EntitySpecifics::kAutofillFieldNumber;
174 case AUTOFILL_PROFILE:
175 return sync_pb::EntitySpecifics::kAutofillProfileFieldNumber;
176 case THEMES:
177 return sync_pb::EntitySpecifics::kThemeFieldNumber;
178 case TYPED_URLS:
179 return sync_pb::EntitySpecifics::kTypedUrlFieldNumber;
180 case EXTENSIONS:
181 return sync_pb::EntitySpecifics::kExtensionFieldNumber;
182 case NIGORI:
183 return sync_pb::EntitySpecifics::kNigoriFieldNumber;
184 case SEARCH_ENGINES:
185 return sync_pb::EntitySpecifics::kSearchEngineFieldNumber;
186 case SESSIONS:
187 return sync_pb::EntitySpecifics::kSessionFieldNumber;
188 case APPS:
189 return sync_pb::EntitySpecifics::kAppFieldNumber;
190 case APP_LIST:
191 return sync_pb::EntitySpecifics::kAppListFieldNumber;
192 case APP_SETTINGS:
193 return sync_pb::EntitySpecifics::kAppSettingFieldNumber;
194 case EXTENSION_SETTINGS:
195 return sync_pb::EntitySpecifics::kExtensionSettingFieldNumber;
196 case APP_NOTIFICATIONS:
197 return sync_pb::EntitySpecifics::kAppNotificationFieldNumber;
198 case HISTORY_DELETE_DIRECTIVES:
199 return sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber;
200 case SYNCED_NOTIFICATIONS:
201 return sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber;
202 case SYNCED_NOTIFICATION_APP_INFO:
203 return sync_pb::EntitySpecifics::kSyncedNotificationAppInfoFieldNumber;
204 case DEVICE_INFO:
205 return sync_pb::EntitySpecifics::kDeviceInfoFieldNumber;
206 case EXPERIMENTS:
207 return sync_pb::EntitySpecifics::kExperimentsFieldNumber;
208 case PRIORITY_PREFERENCES:
209 return sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber;
210 case DICTIONARY:
211 return sync_pb::EntitySpecifics::kDictionaryFieldNumber;
212 case FAVICON_IMAGES:
213 return sync_pb::EntitySpecifics::kFaviconImageFieldNumber;
214 case FAVICON_TRACKING:
215 return sync_pb::EntitySpecifics::kFaviconTrackingFieldNumber;
216 case SUPERVISED_USER_SETTINGS:
217 return sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber;
218 case SUPERVISED_USERS:
219 return sync_pb::EntitySpecifics::kManagedUserFieldNumber;
220 case SUPERVISED_USER_SHARED_SETTINGS:
221 return sync_pb::EntitySpecifics::kManagedUserSharedSettingFieldNumber;
222 case ARTICLES:
223 return sync_pb::EntitySpecifics::kArticleFieldNumber;
224 case WIFI_CREDENTIALS:
225 return sync_pb::EntitySpecifics::kWifiCredentialFieldNumber;
226 default:
227 NOTREACHED() << "No known extension for model type.";
228 return 0;
232 FullModelTypeSet ToFullModelTypeSet(ModelTypeSet in) {
233 FullModelTypeSet out;
234 for (ModelTypeSet::Iterator i = in.First(); i.Good(); i.Inc()) {
235 out.Put(i.Get());
237 return out;
240 // Note: keep this consistent with GetModelType in entry.cc!
241 ModelType GetModelType(const sync_pb::SyncEntity& sync_entity) {
242 DCHECK(!IsRoot(sync_entity)); // Root shouldn't ever go over the wire.
244 // Backwards compatibility with old (pre-specifics) protocol.
245 if (sync_entity.has_bookmarkdata())
246 return BOOKMARKS;
248 ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics());
249 if (specifics_type != UNSPECIFIED)
250 return specifics_type;
252 // Loose check for server-created top-level folders that aren't
253 // bound to a particular model type.
254 if (!sync_entity.server_defined_unique_tag().empty() &&
255 IsFolder(sync_entity)) {
256 return TOP_LEVEL_FOLDER;
259 // This is an item of a datatype we can't understand. Maybe it's
260 // from the future? Either we mis-encoded the object, or the
261 // server sent us entries it shouldn't have.
262 NOTREACHED() << "Unknown datatype in sync proto.";
263 return UNSPECIFIED;
266 ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
267 if (specifics.has_bookmark())
268 return BOOKMARKS;
270 if (specifics.has_password())
271 return PASSWORDS;
273 if (specifics.has_preference())
274 return PREFERENCES;
276 if (specifics.has_autofill())
277 return AUTOFILL;
279 if (specifics.has_autofill_profile())
280 return AUTOFILL_PROFILE;
282 if (specifics.has_theme())
283 return THEMES;
285 if (specifics.has_typed_url())
286 return TYPED_URLS;
288 if (specifics.has_extension())
289 return EXTENSIONS;
291 if (specifics.has_nigori())
292 return NIGORI;
294 if (specifics.has_app())
295 return APPS;
297 if (specifics.has_app_list())
298 return APP_LIST;
300 if (specifics.has_search_engine())
301 return SEARCH_ENGINES;
303 if (specifics.has_session())
304 return SESSIONS;
306 if (specifics.has_app_setting())
307 return APP_SETTINGS;
309 if (specifics.has_extension_setting())
310 return EXTENSION_SETTINGS;
312 if (specifics.has_app_notification())
313 return APP_NOTIFICATIONS;
315 if (specifics.has_history_delete_directive())
316 return HISTORY_DELETE_DIRECTIVES;
318 if (specifics.has_synced_notification())
319 return SYNCED_NOTIFICATIONS;
321 if (specifics.has_synced_notification_app_info())
322 return SYNCED_NOTIFICATION_APP_INFO;
324 if (specifics.has_device_info())
325 return DEVICE_INFO;
327 if (specifics.has_experiments())
328 return EXPERIMENTS;
330 if (specifics.has_priority_preference())
331 return PRIORITY_PREFERENCES;
333 if (specifics.has_dictionary())
334 return DICTIONARY;
336 if (specifics.has_favicon_image())
337 return FAVICON_IMAGES;
339 if (specifics.has_favicon_tracking())
340 return FAVICON_TRACKING;
342 if (specifics.has_managed_user_setting())
343 return SUPERVISED_USER_SETTINGS;
345 if (specifics.has_managed_user())
346 return SUPERVISED_USERS;
348 if (specifics.has_managed_user_shared_setting())
349 return SUPERVISED_USER_SHARED_SETTINGS;
351 if (specifics.has_article())
352 return ARTICLES;
354 if (specifics.has_wifi_credential())
355 return WIFI_CREDENTIALS;
357 return UNSPECIFIED;
360 ModelTypeSet ProtocolTypes() {
361 ModelTypeSet set = ModelTypeSet::All();
362 set.RemoveAll(ProxyTypes());
363 return set;
366 ModelTypeSet UserTypes() {
367 ModelTypeSet set;
368 // TODO(sync): We should be able to build the actual enumset's internal
369 // bitset value here at compile time, rather than performing an iteration
370 // every time.
371 for (int i = FIRST_USER_MODEL_TYPE; i <= LAST_USER_MODEL_TYPE; ++i) {
372 set.Put(ModelTypeFromInt(i));
374 return set;
377 ModelTypeSet UserSelectableTypes() {
378 ModelTypeSet set;
379 // Although the order doesn't technically matter here, it's clearer to keep
380 // these in the same order as their definition in the ModelType enum.
381 set.Put(BOOKMARKS);
382 set.Put(PREFERENCES);
383 set.Put(PASSWORDS);
384 set.Put(AUTOFILL);
385 set.Put(THEMES);
386 set.Put(TYPED_URLS);
387 set.Put(EXTENSIONS);
388 set.Put(APPS);
389 set.Put(WIFI_CREDENTIALS);
390 set.Put(PROXY_TABS);
391 return set;
394 bool IsUserSelectableType(ModelType model_type) {
395 return UserSelectableTypes().Has(model_type);
398 ModelTypeNameMap GetUserSelectableTypeNameMap() {
399 ModelTypeNameMap type_names;
400 ModelTypeSet type_set = UserSelectableTypes();
401 ModelTypeSet::Iterator it = type_set.First();
402 DCHECK_EQ(arraysize(kUserSelectableDataTypeNames), type_set.Size());
403 for (size_t i = 0; i < arraysize(kUserSelectableDataTypeNames) && it.Good();
404 ++i, it.Inc()) {
405 type_names[it.Get()] = kUserSelectableDataTypeNames[i];
407 return type_names;
410 ModelTypeSet EncryptableUserTypes() {
411 ModelTypeSet encryptable_user_types = UserTypes();
412 // We never encrypt history delete directives.
413 encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
414 // Synced notifications are not encrypted since the server must see changes.
415 encryptable_user_types.Remove(SYNCED_NOTIFICATIONS);
416 // Synced Notification App Info does not have private data, so it is not
417 // encrypted.
418 encryptable_user_types.Remove(SYNCED_NOTIFICATION_APP_INFO);
419 // Device info data is not encrypted because it might be synced before
420 // encryption is ready.
421 encryptable_user_types.Remove(DEVICE_INFO);
422 // Priority preferences are not encrypted because they might be synced before
423 // encryption is ready.
424 encryptable_user_types.Remove(PRIORITY_PREFERENCES);
425 // Supervised user settings are not encrypted since they are set server-side.
426 encryptable_user_types.Remove(SUPERVISED_USER_SETTINGS);
427 // Supervised users are not encrypted since they are managed server-side.
428 encryptable_user_types.Remove(SUPERVISED_USERS);
429 // Supervised user shared settings are not encrypted since they are managed
430 // server-side and shared between manager and supervised user.
431 encryptable_user_types.Remove(SUPERVISED_USER_SHARED_SETTINGS);
432 // Proxy types have no sync representation and are therefore not encrypted.
433 // Note however that proxy types map to one or more protocol types, which
434 // may or may not be encrypted themselves.
435 encryptable_user_types.RemoveAll(ProxyTypes());
436 return encryptable_user_types;
439 ModelTypeSet PriorityUserTypes() {
440 return ModelTypeSet(DEVICE_INFO, PRIORITY_PREFERENCES);
443 ModelTypeSet ControlTypes() {
444 ModelTypeSet set;
445 // TODO(sync): We should be able to build the actual enumset's internal
446 // bitset value here at compile time, rather than performing an iteration
447 // every time.
448 for (int i = FIRST_CONTROL_MODEL_TYPE; i <= LAST_CONTROL_MODEL_TYPE; ++i) {
449 set.Put(ModelTypeFromInt(i));
452 return set;
455 ModelTypeSet ProxyTypes() {
456 ModelTypeSet set;
457 set.Put(PROXY_TABS);
458 return set;
461 bool IsControlType(ModelType model_type) {
462 return ControlTypes().Has(model_type);
465 ModelTypeSet CoreTypes() {
466 syncer::ModelTypeSet result;
467 result.PutAll(PriorityCoreTypes());
469 // The following are low priority core types.
470 result.Put(SYNCED_NOTIFICATIONS);
471 result.Put(SYNCED_NOTIFICATION_APP_INFO);
472 result.Put(SUPERVISED_USER_SHARED_SETTINGS);
474 return result;
477 ModelTypeSet PriorityCoreTypes() {
478 syncer::ModelTypeSet result;
479 result.PutAll(ControlTypes());
481 // The following are non-control core types.
482 result.Put(SUPERVISED_USERS);
483 result.Put(SUPERVISED_USER_SETTINGS);
485 return result;
488 ModelTypeSet BackupTypes() {
489 ModelTypeSet result;
490 result.Put(BOOKMARKS);
491 result.Put(PREFERENCES);
492 result.Put(THEMES);
493 result.Put(EXTENSIONS);
494 result.Put(SEARCH_ENGINES);
495 result.Put(APPS);
496 result.Put(APP_LIST);
497 result.Put(APP_SETTINGS);
498 result.Put(EXTENSION_SETTINGS);
499 result.Put(PRIORITY_PREFERENCES);
500 return result;
503 const char* ModelTypeToString(ModelType model_type) {
504 // This is used in serialization routines as well as for displaying debug
505 // information. Do not attempt to change these string values unless you know
506 // what you're doing.
507 switch (model_type) {
508 case TOP_LEVEL_FOLDER:
509 return "Top Level Folder";
510 case UNSPECIFIED:
511 return "Unspecified";
512 case BOOKMARKS:
513 return "Bookmarks";
514 case PREFERENCES:
515 return "Preferences";
516 case PASSWORDS:
517 return "Passwords";
518 case AUTOFILL:
519 return "Autofill";
520 case THEMES:
521 return "Themes";
522 case TYPED_URLS:
523 return "Typed URLs";
524 case EXTENSIONS:
525 return "Extensions";
526 case NIGORI:
527 return "Encryption keys";
528 case SEARCH_ENGINES:
529 return "Search Engines";
530 case SESSIONS:
531 return "Sessions";
532 case APPS:
533 return "Apps";
534 case APP_LIST:
535 return "App List";
536 case AUTOFILL_PROFILE:
537 return "Autofill Profiles";
538 case APP_SETTINGS:
539 return "App settings";
540 case EXTENSION_SETTINGS:
541 return "Extension settings";
542 case APP_NOTIFICATIONS:
543 return "App Notifications";
544 case HISTORY_DELETE_DIRECTIVES:
545 return "History Delete Directives";
546 case SYNCED_NOTIFICATIONS:
547 return "Synced Notifications";
548 case SYNCED_NOTIFICATION_APP_INFO:
549 return "Synced Notification App Info";
550 case DEVICE_INFO:
551 return "Device Info";
552 case EXPERIMENTS:
553 return "Experiments";
554 case PRIORITY_PREFERENCES:
555 return "Priority Preferences";
556 case DICTIONARY:
557 return "Dictionary";
558 case FAVICON_IMAGES:
559 return "Favicon Images";
560 case FAVICON_TRACKING:
561 return "Favicon Tracking";
562 case SUPERVISED_USER_SETTINGS:
563 return "Managed User Settings";
564 case SUPERVISED_USERS:
565 return "Managed Users";
566 case SUPERVISED_USER_SHARED_SETTINGS:
567 return "Managed User Shared Settings";
568 case ARTICLES:
569 return "Articles";
570 case WIFI_CREDENTIALS:
571 return "WiFi Credentials";
572 case PROXY_TABS:
573 return "Tabs";
574 default:
575 break;
577 NOTREACHED() << "No known extension for model type.";
578 return "INVALID";
581 // The normal rules about histograms apply here. Always append to the bottom of
582 // the list, and be careful to not reuse integer values that have already been
583 // assigned. Don't forget to update histograms.xml when you make changes to
584 // this list.
585 int ModelTypeToHistogramInt(ModelType model_type) {
586 switch (model_type) {
587 case UNSPECIFIED:
588 return 0;
589 case TOP_LEVEL_FOLDER:
590 return 1;
591 case BOOKMARKS:
592 return 2;
593 case PREFERENCES:
594 return 3;
595 case PASSWORDS:
596 return 4;
597 case AUTOFILL_PROFILE:
598 return 5;
599 case AUTOFILL:
600 return 6;
601 case THEMES:
602 return 7;
603 case TYPED_URLS:
604 return 8;
605 case EXTENSIONS:
606 return 9;
607 case SEARCH_ENGINES:
608 return 10;
609 case SESSIONS:
610 return 11;
611 case APPS:
612 return 12;
613 case APP_SETTINGS:
614 return 13;
615 case EXTENSION_SETTINGS:
616 return 14;
617 case APP_NOTIFICATIONS:
618 return 15;
619 case HISTORY_DELETE_DIRECTIVES:
620 return 16;
621 case NIGORI:
622 return 17;
623 case DEVICE_INFO:
624 return 18;
625 case EXPERIMENTS:
626 return 19;
627 case SYNCED_NOTIFICATIONS:
628 return 20;
629 case PRIORITY_PREFERENCES:
630 return 21;
631 case DICTIONARY:
632 return 22;
633 case FAVICON_IMAGES:
634 return 23;
635 case FAVICON_TRACKING:
636 return 24;
637 case PROXY_TABS:
638 return 25;
639 case SUPERVISED_USER_SETTINGS:
640 return 26;
641 case SUPERVISED_USERS:
642 return 27;
643 case ARTICLES:
644 return 28;
645 case APP_LIST:
646 return 29;
647 case SUPERVISED_USER_SHARED_SETTINGS:
648 return 30;
649 case SYNCED_NOTIFICATION_APP_INFO:
650 return 31;
651 case WIFI_CREDENTIALS:
652 return 32;
653 // Silence a compiler warning.
654 case MODEL_TYPE_COUNT:
655 return 0;
657 return 0;
660 base::StringValue* ModelTypeToValue(ModelType model_type) {
661 if (model_type >= FIRST_REAL_MODEL_TYPE) {
662 return new base::StringValue(ModelTypeToString(model_type));
663 } else if (model_type == TOP_LEVEL_FOLDER) {
664 return new base::StringValue("Top-level folder");
665 } else if (model_type == UNSPECIFIED) {
666 return new base::StringValue("Unspecified");
668 NOTREACHED();
669 return new base::StringValue(std::string());
672 ModelType ModelTypeFromValue(const base::Value& value) {
673 if (value.IsType(base::Value::TYPE_STRING)) {
674 std::string result;
675 CHECK(value.GetAsString(&result));
676 return ModelTypeFromString(result);
677 } else if (value.IsType(base::Value::TYPE_INTEGER)) {
678 int result;
679 CHECK(value.GetAsInteger(&result));
680 return ModelTypeFromInt(result);
681 } else {
682 NOTREACHED() << "Unsupported value type: " << value.GetType();
683 return UNSPECIFIED;
687 ModelType ModelTypeFromString(const std::string& model_type_string) {
688 if (model_type_string == "Bookmarks")
689 return BOOKMARKS;
690 else if (model_type_string == "Preferences")
691 return PREFERENCES;
692 else if (model_type_string == "Passwords")
693 return PASSWORDS;
694 else if (model_type_string == "Autofill")
695 return AUTOFILL;
696 else if (model_type_string == "Autofill Profiles")
697 return AUTOFILL_PROFILE;
698 else if (model_type_string == "Themes")
699 return THEMES;
700 else if (model_type_string == "Typed URLs")
701 return TYPED_URLS;
702 else if (model_type_string == "Extensions")
703 return EXTENSIONS;
704 else if (model_type_string == "Encryption keys")
705 return NIGORI;
706 else if (model_type_string == "Search Engines")
707 return SEARCH_ENGINES;
708 else if (model_type_string == "Sessions")
709 return SESSIONS;
710 else if (model_type_string == "Apps")
711 return APPS;
712 else if (model_type_string == "App List")
713 return APP_LIST;
714 else if (model_type_string == "App settings")
715 return APP_SETTINGS;
716 else if (model_type_string == "Extension settings")
717 return EXTENSION_SETTINGS;
718 else if (model_type_string == "App Notifications")
719 return APP_NOTIFICATIONS;
720 else if (model_type_string == "History Delete Directives")
721 return HISTORY_DELETE_DIRECTIVES;
722 else if (model_type_string == "Synced Notifications")
723 return SYNCED_NOTIFICATIONS;
724 else if (model_type_string == "Synced Notification App Info")
725 return SYNCED_NOTIFICATION_APP_INFO;
726 else if (model_type_string == "Device Info")
727 return DEVICE_INFO;
728 else if (model_type_string == "Experiments")
729 return EXPERIMENTS;
730 else if (model_type_string == "Priority Preferences")
731 return PRIORITY_PREFERENCES;
732 else if (model_type_string == "Dictionary")
733 return DICTIONARY;
734 else if (model_type_string == "Favicon Images")
735 return FAVICON_IMAGES;
736 else if (model_type_string == "Favicon Tracking")
737 return FAVICON_TRACKING;
738 else if (model_type_string == "Managed User Settings")
739 return SUPERVISED_USER_SETTINGS;
740 else if (model_type_string == "Managed Users")
741 return SUPERVISED_USERS;
742 else if (model_type_string == "Managed User Shared Settings")
743 return SUPERVISED_USER_SHARED_SETTINGS;
744 else if (model_type_string == "Articles")
745 return ARTICLES;
746 else if (model_type_string == "WiFi Credentials")
747 return WIFI_CREDENTIALS;
748 else if (model_type_string == "Tabs")
749 return PROXY_TABS;
750 else
751 NOTREACHED() << "No known model type corresponding to "
752 << model_type_string << ".";
753 return UNSPECIFIED;
756 std::string ModelTypeSetToString(ModelTypeSet model_types) {
757 std::string result;
758 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
759 if (!result.empty()) {
760 result += ", ";
762 result += ModelTypeToString(it.Get());
764 return result;
767 ModelTypeSet ModelTypeSetFromString(const std::string& model_types_string) {
768 std::string working_copy = model_types_string;
769 ModelTypeSet model_types;
770 while (!working_copy.empty()) {
771 // Remove any leading spaces.
772 working_copy = working_copy.substr(working_copy.find_first_not_of(' '));
773 if (working_copy.empty())
774 break;
775 std::string type_str;
776 size_t end = working_copy.find(',');
777 if (end == std::string::npos) {
778 end = working_copy.length() - 1;
779 type_str = working_copy;
780 } else {
781 type_str = working_copy.substr(0, end);
783 syncer::ModelType type = ModelTypeFromString(type_str);
784 if (IsRealDataType(type))
785 model_types.Put(type);
786 working_copy = working_copy.substr(end + 1);
788 return model_types;
791 base::ListValue* ModelTypeSetToValue(ModelTypeSet model_types) {
792 base::ListValue* value = new base::ListValue();
793 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
794 value->Append(new base::StringValue(ModelTypeToString(it.Get())));
796 return value;
799 ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value) {
800 ModelTypeSet result;
801 for (base::ListValue::const_iterator i = value.begin();
802 i != value.end(); ++i) {
803 result.Put(ModelTypeFromValue(**i));
805 return result;
808 // TODO(zea): remove all hardcoded tags in model associators and have them use
809 // this instead.
810 // NOTE: Proxy types should return empty strings (so that we don't NOTREACHED
811 // in tests when we verify they have no root node).
812 std::string ModelTypeToRootTag(ModelType type) {
813 switch (type) {
814 case BOOKMARKS:
815 return "google_chrome_bookmarks";
816 case PREFERENCES:
817 return "google_chrome_preferences";
818 case PASSWORDS:
819 return "google_chrome_passwords";
820 case AUTOFILL:
821 return "google_chrome_autofill";
822 case THEMES:
823 return "google_chrome_themes";
824 case TYPED_URLS:
825 return "google_chrome_typed_urls";
826 case EXTENSIONS:
827 return "google_chrome_extensions";
828 case NIGORI:
829 return "google_chrome_nigori";
830 case SEARCH_ENGINES:
831 return "google_chrome_search_engines";
832 case SESSIONS:
833 return "google_chrome_sessions";
834 case APPS:
835 return "google_chrome_apps";
836 case APP_LIST:
837 return "google_chrome_app_list";
838 case AUTOFILL_PROFILE:
839 return "google_chrome_autofill_profiles";
840 case APP_SETTINGS:
841 return "google_chrome_app_settings";
842 case EXTENSION_SETTINGS:
843 return "google_chrome_extension_settings";
844 case APP_NOTIFICATIONS:
845 return "google_chrome_app_notifications";
846 case HISTORY_DELETE_DIRECTIVES:
847 return "google_chrome_history_delete_directives";
848 case SYNCED_NOTIFICATIONS:
849 return "google_chrome_synced_notifications";
850 case SYNCED_NOTIFICATION_APP_INFO:
851 return "google_chrome_synced_notification_app_info";
852 case DEVICE_INFO:
853 return "google_chrome_device_info";
854 case EXPERIMENTS:
855 return "google_chrome_experiments";
856 case PRIORITY_PREFERENCES:
857 return "google_chrome_priority_preferences";
858 case DICTIONARY:
859 return "google_chrome_dictionary";
860 case FAVICON_IMAGES:
861 return "google_chrome_favicon_images";
862 case FAVICON_TRACKING:
863 return "google_chrome_favicon_tracking";
864 case SUPERVISED_USER_SETTINGS:
865 return "google_chrome_managed_user_settings";
866 case SUPERVISED_USERS:
867 return "google_chrome_managed_users";
868 case SUPERVISED_USER_SHARED_SETTINGS:
869 return "google_chrome_managed_user_shared_settings";
870 case ARTICLES:
871 return "google_chrome_articles";
872 case WIFI_CREDENTIALS:
873 return "google_chrome_wifi_credentials";
874 case PROXY_TABS:
875 return std::string();
876 default:
877 break;
879 NOTREACHED() << "No known extension for model type.";
880 return "INVALID";
883 // TODO(akalin): Figure out a better way to do these mappings.
884 // Note: Do not include proxy types in this list. They should never receive
885 // or trigger notifications.
886 namespace {
887 const char kBookmarkNotificationType[] = "BOOKMARK";
888 const char kPreferenceNotificationType[] = "PREFERENCE";
889 const char kPasswordNotificationType[] = "PASSWORD";
890 const char kAutofillNotificationType[] = "AUTOFILL";
891 const char kThemeNotificationType[] = "THEME";
892 const char kTypedUrlNotificationType[] = "TYPED_URL";
893 const char kExtensionNotificationType[] = "EXTENSION";
894 const char kExtensionSettingNotificationType[] = "EXTENSION_SETTING";
895 const char kNigoriNotificationType[] = "NIGORI";
896 const char kAppSettingNotificationType[] = "APP_SETTING";
897 const char kAppNotificationType[] = "APP";
898 const char kAppListNotificationType[] = "APP_LIST";
899 const char kSearchEngineNotificationType[] = "SEARCH_ENGINE";
900 const char kSessionNotificationType[] = "SESSION";
901 const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE";
902 const char kAppNotificationNotificationType[] = "APP_NOTIFICATION";
903 const char kHistoryDeleteDirectiveNotificationType[] =
904 "HISTORY_DELETE_DIRECTIVE";
905 const char kSyncedNotificationType[] = "SYNCED_NOTIFICATION";
906 const char kSyncedNotificationAppInfoType[] = "SYNCED_NOTIFICATION_APP_INFO";
907 const char kDeviceInfoNotificationType[] = "DEVICE_INFO";
908 const char kExperimentsNotificationType[] = "EXPERIMENTS";
909 const char kPriorityPreferenceNotificationType[] = "PRIORITY_PREFERENCE";
910 const char kDictionaryNotificationType[] = "DICTIONARY";
911 const char kFaviconImageNotificationType[] = "FAVICON_IMAGE";
912 const char kFaviconTrackingNotificationType[] = "FAVICON_TRACKING";
913 const char kSupervisedUserSettingNotificationType[] = "MANAGED_USER_SETTING";
914 const char kSupervisedUserNotificationType[] = "MANAGED_USER";
915 const char kSupervisedUserSharedSettingNotificationType[] =
916 "MANAGED_USER_SHARED_SETTING";
917 const char kArticleNotificationType[] = "ARTICLE";
918 } // namespace
920 bool RealModelTypeToNotificationType(ModelType model_type,
921 std::string* notification_type) {
922 switch (model_type) {
923 case BOOKMARKS:
924 *notification_type = kBookmarkNotificationType;
925 return true;
926 case PREFERENCES:
927 *notification_type = kPreferenceNotificationType;
928 return true;
929 case PASSWORDS:
930 *notification_type = kPasswordNotificationType;
931 return true;
932 case AUTOFILL:
933 *notification_type = kAutofillNotificationType;
934 return true;
935 case THEMES:
936 *notification_type = kThemeNotificationType;
937 return true;
938 case TYPED_URLS:
939 *notification_type = kTypedUrlNotificationType;
940 return true;
941 case EXTENSIONS:
942 *notification_type = kExtensionNotificationType;
943 return true;
944 case NIGORI:
945 *notification_type = kNigoriNotificationType;
946 return true;
947 case APP_SETTINGS:
948 *notification_type = kAppSettingNotificationType;
949 return true;
950 case APPS:
951 *notification_type = kAppNotificationType;
952 return true;
953 case APP_LIST:
954 *notification_type = kAppListNotificationType;
955 return true;
956 case SEARCH_ENGINES:
957 *notification_type = kSearchEngineNotificationType;
958 return true;
959 case SESSIONS:
960 *notification_type = kSessionNotificationType;
961 return true;
962 case AUTOFILL_PROFILE:
963 *notification_type = kAutofillProfileNotificationType;
964 return true;
965 case EXTENSION_SETTINGS:
966 *notification_type = kExtensionSettingNotificationType;
967 return true;
968 case APP_NOTIFICATIONS:
969 *notification_type = kAppNotificationNotificationType;
970 return true;
971 case HISTORY_DELETE_DIRECTIVES:
972 *notification_type = kHistoryDeleteDirectiveNotificationType;
973 return true;
974 case SYNCED_NOTIFICATIONS:
975 *notification_type = kSyncedNotificationType;
976 return true;
977 case SYNCED_NOTIFICATION_APP_INFO:
978 *notification_type = kSyncedNotificationAppInfoType;
979 return true;
980 case DEVICE_INFO:
981 *notification_type = kDeviceInfoNotificationType;
982 return true;
983 case EXPERIMENTS:
984 *notification_type = kExperimentsNotificationType;
985 return true;
986 case PRIORITY_PREFERENCES:
987 *notification_type = kPriorityPreferenceNotificationType;
988 return true;
989 case DICTIONARY:
990 *notification_type = kDictionaryNotificationType;
991 return true;
992 case FAVICON_IMAGES:
993 *notification_type = kFaviconImageNotificationType;
994 return true;
995 case FAVICON_TRACKING:
996 *notification_type = kFaviconTrackingNotificationType;
997 return true;
998 case SUPERVISED_USER_SETTINGS:
999 *notification_type = kSupervisedUserSettingNotificationType;
1000 return true;
1001 case SUPERVISED_USERS:
1002 *notification_type = kSupervisedUserNotificationType;
1003 return true;
1004 case SUPERVISED_USER_SHARED_SETTINGS:
1005 *notification_type = kSupervisedUserSharedSettingNotificationType;
1006 return true;
1007 case ARTICLES:
1008 *notification_type = kArticleNotificationType;
1009 return true;
1010 default:
1011 break;
1013 notification_type->clear();
1014 return false;
1017 bool NotificationTypeToRealModelType(const std::string& notification_type,
1018 ModelType* model_type) {
1019 if (notification_type == kBookmarkNotificationType) {
1020 *model_type = BOOKMARKS;
1021 return true;
1022 } else if (notification_type == kPreferenceNotificationType) {
1023 *model_type = PREFERENCES;
1024 return true;
1025 } else if (notification_type == kPasswordNotificationType) {
1026 *model_type = PASSWORDS;
1027 return true;
1028 } else if (notification_type == kAutofillNotificationType) {
1029 *model_type = AUTOFILL;
1030 return true;
1031 } else if (notification_type == kThemeNotificationType) {
1032 *model_type = THEMES;
1033 return true;
1034 } else if (notification_type == kTypedUrlNotificationType) {
1035 *model_type = TYPED_URLS;
1036 return true;
1037 } else if (notification_type == kExtensionNotificationType) {
1038 *model_type = EXTENSIONS;
1039 return true;
1040 } else if (notification_type == kNigoriNotificationType) {
1041 *model_type = NIGORI;
1042 return true;
1043 } else if (notification_type == kAppNotificationType) {
1044 *model_type = APPS;
1045 return true;
1046 } else if (notification_type == kAppListNotificationType) {
1047 *model_type = APP_LIST;
1048 return true;
1049 } else if (notification_type == kSearchEngineNotificationType) {
1050 *model_type = SEARCH_ENGINES;
1051 return true;
1052 } else if (notification_type == kSessionNotificationType) {
1053 *model_type = SESSIONS;
1054 return true;
1055 } else if (notification_type == kAutofillProfileNotificationType) {
1056 *model_type = AUTOFILL_PROFILE;
1057 return true;
1058 } else if (notification_type == kAppSettingNotificationType) {
1059 *model_type = APP_SETTINGS;
1060 return true;
1061 } else if (notification_type == kExtensionSettingNotificationType) {
1062 *model_type = EXTENSION_SETTINGS;
1063 return true;
1064 } else if (notification_type == kAppNotificationNotificationType) {
1065 *model_type = APP_NOTIFICATIONS;
1066 return true;
1067 } else if (notification_type == kHistoryDeleteDirectiveNotificationType) {
1068 *model_type = HISTORY_DELETE_DIRECTIVES;
1069 return true;
1070 } else if (notification_type == kSyncedNotificationType) {
1071 *model_type = SYNCED_NOTIFICATIONS;
1072 return true;
1073 } else if (notification_type == kSyncedNotificationAppInfoType) {
1074 *model_type = SYNCED_NOTIFICATION_APP_INFO;
1075 return true;
1076 } else if (notification_type == kDeviceInfoNotificationType) {
1077 *model_type = DEVICE_INFO;
1078 return true;
1079 } else if (notification_type == kExperimentsNotificationType) {
1080 *model_type = EXPERIMENTS;
1081 return true;
1082 } else if (notification_type == kPriorityPreferenceNotificationType) {
1083 *model_type = PRIORITY_PREFERENCES;
1084 return true;
1085 } else if (notification_type == kDictionaryNotificationType) {
1086 *model_type = DICTIONARY;
1087 return true;
1088 } else if (notification_type == kFaviconImageNotificationType) {
1089 *model_type = FAVICON_IMAGES;
1090 return true;
1091 } else if (notification_type == kFaviconTrackingNotificationType) {
1092 *model_type = FAVICON_TRACKING;
1093 return true;
1094 } else if (notification_type == kSupervisedUserSettingNotificationType) {
1095 *model_type = SUPERVISED_USER_SETTINGS;
1096 return true;
1097 } else if (notification_type == kSupervisedUserNotificationType) {
1098 *model_type = SUPERVISED_USERS;
1099 return true;
1100 } else if (notification_type ==
1101 kSupervisedUserSharedSettingNotificationType) {
1102 *model_type = SUPERVISED_USER_SHARED_SETTINGS;
1103 return true;
1104 } else if (notification_type == kArticleNotificationType) {
1105 *model_type = ARTICLES;
1106 return true;
1108 *model_type = UNSPECIFIED;
1109 return false;
1112 bool IsRealDataType(ModelType model_type) {
1113 return model_type >= FIRST_REAL_MODEL_TYPE && model_type < MODEL_TYPE_COUNT;
1116 bool IsProxyType(ModelType model_type) {
1117 return model_type >= FIRST_PROXY_TYPE && model_type <= LAST_PROXY_TYPE;
1120 bool IsActOnceDataType(ModelType model_type) {
1121 return model_type == HISTORY_DELETE_DIRECTIVES;
1124 } // namespace syncer