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"
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
33 const char* kUserSelectableDataTypeNames
[] = {
47 36 == 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.";
58 specifics
->mutable_bookmark();
61 specifics
->mutable_password();
64 specifics
->mutable_preference();
67 specifics
->mutable_autofill();
69 case AUTOFILL_PROFILE
:
70 specifics
->mutable_autofill_profile();
72 case AUTOFILL_WALLET_DATA
:
73 specifics
->mutable_autofill_wallet();
75 case AUTOFILL_WALLET_METADATA
:
76 specifics
->mutable_wallet_metadata();
79 specifics
->mutable_theme();
82 specifics
->mutable_typed_url();
85 specifics
->mutable_extension();
88 specifics
->mutable_nigori();
91 specifics
->mutable_search_engine();
94 specifics
->mutable_session();
97 specifics
->mutable_app();
100 specifics
->mutable_app_list();
103 specifics
->mutable_app_setting();
105 case EXTENSION_SETTINGS
:
106 specifics
->mutable_extension_setting();
108 case APP_NOTIFICATIONS
:
109 specifics
->mutable_app_notification();
111 case HISTORY_DELETE_DIRECTIVES
:
112 specifics
->mutable_history_delete_directive();
114 case SYNCED_NOTIFICATIONS
:
115 specifics
->mutable_synced_notification();
117 case SYNCED_NOTIFICATION_APP_INFO
:
118 specifics
->mutable_synced_notification_app_info();
121 specifics
->mutable_device_info();
124 specifics
->mutable_experiments();
126 case PRIORITY_PREFERENCES
:
127 specifics
->mutable_priority_preference();
130 specifics
->mutable_dictionary();
133 specifics
->mutable_favicon_image();
135 case FAVICON_TRACKING
:
136 specifics
->mutable_favicon_tracking();
138 case SUPERVISED_USER_SETTINGS
:
139 specifics
->mutable_managed_user_setting();
141 case SUPERVISED_USERS
:
142 specifics
->mutable_managed_user();
144 case SUPERVISED_USER_SHARED_SETTINGS
:
145 specifics
->mutable_managed_user_shared_setting();
147 case SUPERVISED_USER_WHITELISTS
:
148 specifics
->mutable_managed_user_whitelist();
151 specifics
->mutable_article();
153 case WIFI_CREDENTIALS
:
154 specifics
->mutable_wifi_credential();
157 NOTREACHED() << "No known extension for model type.";
161 ModelType
GetModelTypeFromSpecificsFieldNumber(int field_number
) {
162 ModelTypeSet protocol_types
= ProtocolTypes();
163 for (ModelTypeSet::Iterator iter
= protocol_types
.First(); iter
.Good();
165 if (GetSpecificsFieldNumberFromModelType(iter
.Get()) == field_number
)
171 int GetSpecificsFieldNumberFromModelType(ModelType model_type
) {
172 DCHECK(ProtocolTypes().Has(model_type
))
173 << "Only protocol types have field values.";
174 switch (model_type
) {
176 return sync_pb::EntitySpecifics::kBookmarkFieldNumber
;
178 return sync_pb::EntitySpecifics::kPasswordFieldNumber
;
180 return sync_pb::EntitySpecifics::kPreferenceFieldNumber
;
182 return sync_pb::EntitySpecifics::kAutofillFieldNumber
;
183 case AUTOFILL_PROFILE
:
184 return sync_pb::EntitySpecifics::kAutofillProfileFieldNumber
;
185 case AUTOFILL_WALLET_DATA
:
186 return sync_pb::EntitySpecifics::kAutofillWalletFieldNumber
;
187 case AUTOFILL_WALLET_METADATA
:
188 return sync_pb::EntitySpecifics::kWalletMetadataFieldNumber
;
190 return sync_pb::EntitySpecifics::kThemeFieldNumber
;
192 return sync_pb::EntitySpecifics::kTypedUrlFieldNumber
;
194 return sync_pb::EntitySpecifics::kExtensionFieldNumber
;
196 return sync_pb::EntitySpecifics::kNigoriFieldNumber
;
198 return sync_pb::EntitySpecifics::kSearchEngineFieldNumber
;
200 return sync_pb::EntitySpecifics::kSessionFieldNumber
;
202 return sync_pb::EntitySpecifics::kAppFieldNumber
;
204 return sync_pb::EntitySpecifics::kAppListFieldNumber
;
206 return sync_pb::EntitySpecifics::kAppSettingFieldNumber
;
207 case EXTENSION_SETTINGS
:
208 return sync_pb::EntitySpecifics::kExtensionSettingFieldNumber
;
209 case APP_NOTIFICATIONS
:
210 return sync_pb::EntitySpecifics::kAppNotificationFieldNumber
;
211 case HISTORY_DELETE_DIRECTIVES
:
212 return sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber
;
213 case SYNCED_NOTIFICATIONS
:
214 return sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber
;
215 case SYNCED_NOTIFICATION_APP_INFO
:
216 return sync_pb::EntitySpecifics::kSyncedNotificationAppInfoFieldNumber
;
218 return sync_pb::EntitySpecifics::kDeviceInfoFieldNumber
;
220 return sync_pb::EntitySpecifics::kExperimentsFieldNumber
;
221 case PRIORITY_PREFERENCES
:
222 return sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber
;
224 return sync_pb::EntitySpecifics::kDictionaryFieldNumber
;
226 return sync_pb::EntitySpecifics::kFaviconImageFieldNumber
;
227 case FAVICON_TRACKING
:
228 return sync_pb::EntitySpecifics::kFaviconTrackingFieldNumber
;
229 case SUPERVISED_USER_SETTINGS
:
230 return sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber
;
231 case SUPERVISED_USERS
:
232 return sync_pb::EntitySpecifics::kManagedUserFieldNumber
;
233 case SUPERVISED_USER_SHARED_SETTINGS
:
234 return sync_pb::EntitySpecifics::kManagedUserSharedSettingFieldNumber
;
235 case SUPERVISED_USER_WHITELISTS
:
236 return sync_pb::EntitySpecifics::kManagedUserWhitelistFieldNumber
;
238 return sync_pb::EntitySpecifics::kArticleFieldNumber
;
239 case WIFI_CREDENTIALS
:
240 return sync_pb::EntitySpecifics::kWifiCredentialFieldNumber
;
242 NOTREACHED() << "No known extension for model type.";
247 FullModelTypeSet
ToFullModelTypeSet(ModelTypeSet in
) {
248 FullModelTypeSet out
;
249 for (ModelTypeSet::Iterator i
= in
.First(); i
.Good(); i
.Inc()) {
255 // Note: keep this consistent with GetModelType in entry.cc!
256 ModelType
GetModelType(const sync_pb::SyncEntity
& sync_entity
) {
257 DCHECK(!IsRoot(sync_entity
)); // Root shouldn't ever go over the wire.
259 // Backwards compatibility with old (pre-specifics) protocol.
260 if (sync_entity
.has_bookmarkdata())
263 ModelType specifics_type
= GetModelTypeFromSpecifics(sync_entity
.specifics());
264 if (specifics_type
!= UNSPECIFIED
)
265 return specifics_type
;
267 // Loose check for server-created top-level folders that aren't
268 // bound to a particular model type.
269 if (!sync_entity
.server_defined_unique_tag().empty() &&
270 IsFolder(sync_entity
)) {
271 return TOP_LEVEL_FOLDER
;
274 // This is an item of a datatype we can't understand. Maybe it's
275 // from the future? Either we mis-encoded the object, or the
276 // server sent us entries it shouldn't have.
277 NOTREACHED() << "Unknown datatype in sync proto.";
281 ModelType
GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics
& specifics
) {
282 if (specifics
.has_bookmark())
285 if (specifics
.has_password())
288 if (specifics
.has_preference())
291 if (specifics
.has_autofill())
294 if (specifics
.has_autofill_profile())
295 return AUTOFILL_PROFILE
;
297 if (specifics
.has_autofill_wallet())
298 return AUTOFILL_WALLET_DATA
;
300 if (specifics
.has_wallet_metadata())
301 return AUTOFILL_WALLET_METADATA
;
303 if (specifics
.has_theme())
306 if (specifics
.has_typed_url())
309 if (specifics
.has_extension())
312 if (specifics
.has_nigori())
315 if (specifics
.has_app())
318 if (specifics
.has_app_list())
321 if (specifics
.has_search_engine())
322 return SEARCH_ENGINES
;
324 if (specifics
.has_session())
327 if (specifics
.has_app_setting())
330 if (specifics
.has_extension_setting())
331 return EXTENSION_SETTINGS
;
333 if (specifics
.has_app_notification())
334 return APP_NOTIFICATIONS
;
336 if (specifics
.has_history_delete_directive())
337 return HISTORY_DELETE_DIRECTIVES
;
339 if (specifics
.has_synced_notification())
340 return SYNCED_NOTIFICATIONS
;
342 if (specifics
.has_synced_notification_app_info())
343 return SYNCED_NOTIFICATION_APP_INFO
;
345 if (specifics
.has_device_info())
348 if (specifics
.has_experiments())
351 if (specifics
.has_priority_preference())
352 return PRIORITY_PREFERENCES
;
354 if (specifics
.has_dictionary())
357 if (specifics
.has_favicon_image())
358 return FAVICON_IMAGES
;
360 if (specifics
.has_favicon_tracking())
361 return FAVICON_TRACKING
;
363 if (specifics
.has_managed_user_setting())
364 return SUPERVISED_USER_SETTINGS
;
366 if (specifics
.has_managed_user())
367 return SUPERVISED_USERS
;
369 if (specifics
.has_managed_user_shared_setting())
370 return SUPERVISED_USER_SHARED_SETTINGS
;
372 if (specifics
.has_managed_user_whitelist())
373 return SUPERVISED_USER_WHITELISTS
;
375 if (specifics
.has_article())
378 if (specifics
.has_wifi_credential())
379 return WIFI_CREDENTIALS
;
384 ModelTypeSet
ProtocolTypes() {
385 ModelTypeSet set
= ModelTypeSet::All();
386 set
.RemoveAll(ProxyTypes());
390 ModelTypeSet
UserTypes() {
392 // TODO(sync): We should be able to build the actual enumset's internal
393 // bitset value here at compile time, rather than performing an iteration
395 for (int i
= FIRST_USER_MODEL_TYPE
; i
<= LAST_USER_MODEL_TYPE
; ++i
) {
396 set
.Put(ModelTypeFromInt(i
));
401 ModelTypeSet
UserSelectableTypes() {
403 // Although the order doesn't technically matter here, it's clearer to keep
404 // these in the same order as their definition in the ModelType enum.
406 set
.Put(PREFERENCES
);
413 set
.Put(WIFI_CREDENTIALS
);
418 bool IsUserSelectableType(ModelType model_type
) {
419 return UserSelectableTypes().Has(model_type
);
422 ModelTypeNameMap
GetUserSelectableTypeNameMap() {
423 ModelTypeNameMap type_names
;
424 ModelTypeSet type_set
= UserSelectableTypes();
425 ModelTypeSet::Iterator it
= type_set
.First();
426 DCHECK_EQ(arraysize(kUserSelectableDataTypeNames
), type_set
.Size());
427 for (size_t i
= 0; i
< arraysize(kUserSelectableDataTypeNames
) && it
.Good();
429 type_names
[it
.Get()] = kUserSelectableDataTypeNames
[i
];
434 ModelTypeSet
EncryptableUserTypes() {
435 ModelTypeSet encryptable_user_types
= UserTypes();
436 // We never encrypt history delete directives.
437 encryptable_user_types
.Remove(HISTORY_DELETE_DIRECTIVES
);
438 // Synced notifications are not encrypted since the server must see changes.
439 encryptable_user_types
.Remove(SYNCED_NOTIFICATIONS
);
440 // Synced Notification App Info does not have private data, so it is not
442 encryptable_user_types
.Remove(SYNCED_NOTIFICATION_APP_INFO
);
443 // Device info data is not encrypted because it might be synced before
444 // encryption is ready.
445 encryptable_user_types
.Remove(DEVICE_INFO
);
446 // Priority preferences are not encrypted because they might be synced before
447 // encryption is ready.
448 encryptable_user_types
.Remove(PRIORITY_PREFERENCES
);
449 // Supervised user settings are not encrypted since they are set server-side.
450 encryptable_user_types
.Remove(SUPERVISED_USER_SETTINGS
);
451 // Supervised users are not encrypted since they are managed server-side.
452 encryptable_user_types
.Remove(SUPERVISED_USERS
);
453 // Supervised user shared settings are not encrypted since they are managed
454 // server-side and shared between manager and supervised user.
455 encryptable_user_types
.Remove(SUPERVISED_USER_SHARED_SETTINGS
);
456 // Supervised user whitelists are not encrypted since they are managed
458 encryptable_user_types
.Remove(SUPERVISED_USER_WHITELISTS
);
459 // Proxy types have no sync representation and are therefore not encrypted.
460 // Note however that proxy types map to one or more protocol types, which
461 // may or may not be encrypted themselves.
462 encryptable_user_types
.RemoveAll(ProxyTypes());
463 // Wallet data is not encrypted since it actually originates on the server.
464 encryptable_user_types
.Remove(AUTOFILL_WALLET_DATA
);
465 return encryptable_user_types
;
468 ModelTypeSet
PriorityUserTypes() {
469 return ModelTypeSet(DEVICE_INFO
, PRIORITY_PREFERENCES
);
472 ModelTypeSet
ControlTypes() {
474 // TODO(sync): We should be able to build the actual enumset's internal
475 // bitset value here at compile time, rather than performing an iteration
477 for (int i
= FIRST_CONTROL_MODEL_TYPE
; i
<= LAST_CONTROL_MODEL_TYPE
; ++i
) {
478 set
.Put(ModelTypeFromInt(i
));
484 ModelTypeSet
ProxyTypes() {
490 bool IsControlType(ModelType model_type
) {
491 return ControlTypes().Has(model_type
);
494 ModelTypeSet
CoreTypes() {
495 syncer::ModelTypeSet result
;
496 result
.PutAll(PriorityCoreTypes());
498 // The following are low priority core types.
499 result
.Put(SYNCED_NOTIFICATIONS
);
500 result
.Put(SYNCED_NOTIFICATION_APP_INFO
);
501 result
.Put(SUPERVISED_USER_SHARED_SETTINGS
);
502 result
.Put(SUPERVISED_USER_WHITELISTS
);
507 ModelTypeSet
PriorityCoreTypes() {
508 syncer::ModelTypeSet result
;
509 result
.PutAll(ControlTypes());
511 // The following are non-control core types.
512 result
.Put(SUPERVISED_USERS
);
513 result
.Put(SUPERVISED_USER_SETTINGS
);
518 ModelTypeSet
BackupTypes() {
520 result
.Put(BOOKMARKS
);
521 result
.Put(PREFERENCES
);
523 result
.Put(EXTENSIONS
);
524 result
.Put(SEARCH_ENGINES
);
526 result
.Put(APP_LIST
);
527 result
.Put(APP_SETTINGS
);
528 result
.Put(EXTENSION_SETTINGS
);
529 result
.Put(PRIORITY_PREFERENCES
);
533 const char* ModelTypeToString(ModelType model_type
) {
534 // This is used in serialization routines as well as for displaying debug
535 // information. Do not attempt to change these string values unless you know
536 // what you're doing.
537 switch (model_type
) {
538 case TOP_LEVEL_FOLDER
:
539 return "Top Level Folder";
541 return "Unspecified";
545 return "Preferences";
557 return "Encryption keys";
559 return "Search Engines";
566 case AUTOFILL_PROFILE
:
567 return "Autofill Profiles";
569 return "App settings";
570 case EXTENSION_SETTINGS
:
571 return "Extension settings";
572 case APP_NOTIFICATIONS
:
573 return "App Notifications";
574 case HISTORY_DELETE_DIRECTIVES
:
575 return "History Delete Directives";
576 case SYNCED_NOTIFICATIONS
:
577 return "Synced Notifications";
578 case SYNCED_NOTIFICATION_APP_INFO
:
579 return "Synced Notification App Info";
581 return "Device Info";
583 return "Experiments";
584 case PRIORITY_PREFERENCES
:
585 return "Priority Preferences";
589 return "Favicon Images";
590 case FAVICON_TRACKING
:
591 return "Favicon Tracking";
592 case SUPERVISED_USER_SETTINGS
:
593 return "Managed User Settings";
594 case SUPERVISED_USERS
:
595 return "Managed Users";
596 case SUPERVISED_USER_SHARED_SETTINGS
:
597 return "Managed User Shared Settings";
598 case SUPERVISED_USER_WHITELISTS
:
599 return "Managed User Whitelists";
602 case WIFI_CREDENTIALS
:
603 return "WiFi Credentials";
606 case AUTOFILL_WALLET_DATA
:
607 return "Autofill Wallet";
608 case AUTOFILL_WALLET_METADATA
:
609 return "Autofill Wallet Metadata";
613 NOTREACHED() << "No known extension for model type.";
617 // The normal rules about histograms apply here. Always append to the bottom of
618 // the list, and be careful to not reuse integer values that have already been
621 // Don't forget to update the "SyncModelTypes" enum in histograms.xml when you
622 // make changes to this list.
623 int ModelTypeToHistogramInt(ModelType model_type
) {
624 switch (model_type
) {
627 case TOP_LEVEL_FOLDER
:
635 case AUTOFILL_PROFILE
:
653 case EXTENSION_SETTINGS
:
655 case APP_NOTIFICATIONS
:
657 case HISTORY_DELETE_DIRECTIVES
:
665 case SYNCED_NOTIFICATIONS
:
667 case PRIORITY_PREFERENCES
:
673 case FAVICON_TRACKING
:
677 case SUPERVISED_USER_SETTINGS
:
679 case SUPERVISED_USERS
:
685 case SUPERVISED_USER_SHARED_SETTINGS
:
687 case SYNCED_NOTIFICATION_APP_INFO
:
689 case WIFI_CREDENTIALS
:
691 case SUPERVISED_USER_WHITELISTS
:
693 case AUTOFILL_WALLET_DATA
:
695 case AUTOFILL_WALLET_METADATA
:
697 // Silence a compiler warning.
698 case MODEL_TYPE_COUNT
:
704 base::StringValue
* ModelTypeToValue(ModelType model_type
) {
705 if (model_type
>= FIRST_REAL_MODEL_TYPE
) {
706 return new base::StringValue(ModelTypeToString(model_type
));
707 } else if (model_type
== TOP_LEVEL_FOLDER
) {
708 return new base::StringValue("Top-level folder");
709 } else if (model_type
== UNSPECIFIED
) {
710 return new base::StringValue("Unspecified");
713 return new base::StringValue(std::string());
716 ModelType
ModelTypeFromValue(const base::Value
& value
) {
717 if (value
.IsType(base::Value::TYPE_STRING
)) {
719 CHECK(value
.GetAsString(&result
));
720 return ModelTypeFromString(result
);
721 } else if (value
.IsType(base::Value::TYPE_INTEGER
)) {
723 CHECK(value
.GetAsInteger(&result
));
724 return ModelTypeFromInt(result
);
726 NOTREACHED() << "Unsupported value type: " << value
.GetType();
731 ModelType
ModelTypeFromString(const std::string
& model_type_string
) {
732 if (model_type_string
== "Bookmarks")
734 else if (model_type_string
== "Preferences")
736 else if (model_type_string
== "Passwords")
738 else if (model_type_string
== "Autofill")
740 else if (model_type_string
== "Autofill Profiles")
741 return AUTOFILL_PROFILE
;
742 else if (model_type_string
== "Autofill Wallet")
743 return AUTOFILL_WALLET_DATA
;
744 else if (model_type_string
== "Autofill Wallet Metadata")
745 return AUTOFILL_WALLET_METADATA
;
746 else if (model_type_string
== "Themes")
748 else if (model_type_string
== "Typed URLs")
750 else if (model_type_string
== "Extensions")
752 else if (model_type_string
== "Encryption keys")
754 else if (model_type_string
== "Search Engines")
755 return SEARCH_ENGINES
;
756 else if (model_type_string
== "Sessions")
758 else if (model_type_string
== "Apps")
760 else if (model_type_string
== "App List")
762 else if (model_type_string
== "App settings")
764 else if (model_type_string
== "Extension settings")
765 return EXTENSION_SETTINGS
;
766 else if (model_type_string
== "App Notifications")
767 return APP_NOTIFICATIONS
;
768 else if (model_type_string
== "History Delete Directives")
769 return HISTORY_DELETE_DIRECTIVES
;
770 else if (model_type_string
== "Synced Notifications")
771 return SYNCED_NOTIFICATIONS
;
772 else if (model_type_string
== "Synced Notification App Info")
773 return SYNCED_NOTIFICATION_APP_INFO
;
774 else if (model_type_string
== "Device Info")
776 else if (model_type_string
== "Experiments")
778 else if (model_type_string
== "Priority Preferences")
779 return PRIORITY_PREFERENCES
;
780 else if (model_type_string
== "Dictionary")
782 else if (model_type_string
== "Favicon Images")
783 return FAVICON_IMAGES
;
784 else if (model_type_string
== "Favicon Tracking")
785 return FAVICON_TRACKING
;
786 else if (model_type_string
== "Managed User Settings")
787 return SUPERVISED_USER_SETTINGS
;
788 else if (model_type_string
== "Managed Users")
789 return SUPERVISED_USERS
;
790 else if (model_type_string
== "Managed User Shared Settings")
791 return SUPERVISED_USER_SHARED_SETTINGS
;
792 else if (model_type_string
== "Managed User Whitelists")
793 return SUPERVISED_USER_WHITELISTS
;
794 else if (model_type_string
== "Articles")
796 else if (model_type_string
== "WiFi Credentials")
797 return WIFI_CREDENTIALS
;
798 else if (model_type_string
== "Tabs")
801 NOTREACHED() << "No known model type corresponding to "
802 << model_type_string
<< ".";
806 std::string
ModelTypeSetToString(ModelTypeSet model_types
) {
808 for (ModelTypeSet::Iterator it
= model_types
.First(); it
.Good(); it
.Inc()) {
809 if (!result
.empty()) {
812 result
+= ModelTypeToString(it
.Get());
817 ModelTypeSet
ModelTypeSetFromString(const std::string
& model_types_string
) {
818 std::string working_copy
= model_types_string
;
819 ModelTypeSet model_types
;
820 while (!working_copy
.empty()) {
821 // Remove any leading spaces.
822 working_copy
= working_copy
.substr(working_copy
.find_first_not_of(' '));
823 if (working_copy
.empty())
825 std::string type_str
;
826 size_t end
= working_copy
.find(',');
827 if (end
== std::string::npos
) {
828 end
= working_copy
.length() - 1;
829 type_str
= working_copy
;
831 type_str
= working_copy
.substr(0, end
);
833 syncer::ModelType type
= ModelTypeFromString(type_str
);
834 if (IsRealDataType(type
))
835 model_types
.Put(type
);
836 working_copy
= working_copy
.substr(end
+ 1);
841 scoped_ptr
<base::ListValue
> ModelTypeSetToValue(ModelTypeSet model_types
) {
842 scoped_ptr
<base::ListValue
> value(new base::ListValue());
843 for (ModelTypeSet::Iterator it
= model_types
.First(); it
.Good(); it
.Inc()) {
844 value
->AppendString(ModelTypeToString(it
.Get()));
849 ModelTypeSet
ModelTypeSetFromValue(const base::ListValue
& value
) {
851 for (base::ListValue::const_iterator i
= value
.begin();
852 i
!= value
.end(); ++i
) {
853 result
.Put(ModelTypeFromValue(**i
));
858 // TODO(zea): remove all hardcoded tags in model associators and have them use
860 // NOTE: Proxy types should return empty strings (so that we don't NOTREACHED
861 // in tests when we verify they have no root node).
862 std::string
ModelTypeToRootTag(ModelType type
) {
865 return "google_chrome_bookmarks";
867 return "google_chrome_preferences";
869 return "google_chrome_passwords";
871 return "google_chrome_autofill";
873 return "google_chrome_themes";
875 return "google_chrome_typed_urls";
877 return "google_chrome_extensions";
879 return "google_chrome_nigori";
881 return "google_chrome_search_engines";
883 return "google_chrome_sessions";
885 return "google_chrome_apps";
887 return "google_chrome_app_list";
888 case AUTOFILL_PROFILE
:
889 return "google_chrome_autofill_profiles";
890 case AUTOFILL_WALLET_DATA
:
891 return "google_chrome_autofill_wallet";
892 case AUTOFILL_WALLET_METADATA
:
893 return "google_chrome_autofill_wallet_metadata";
895 return "google_chrome_app_settings";
896 case EXTENSION_SETTINGS
:
897 return "google_chrome_extension_settings";
898 case APP_NOTIFICATIONS
:
899 return "google_chrome_app_notifications";
900 case HISTORY_DELETE_DIRECTIVES
:
901 return "google_chrome_history_delete_directives";
902 case SYNCED_NOTIFICATIONS
:
903 return "google_chrome_synced_notifications";
904 case SYNCED_NOTIFICATION_APP_INFO
:
905 return "google_chrome_synced_notification_app_info";
907 return "google_chrome_device_info";
909 return "google_chrome_experiments";
910 case PRIORITY_PREFERENCES
:
911 return "google_chrome_priority_preferences";
913 return "google_chrome_dictionary";
915 return "google_chrome_favicon_images";
916 case FAVICON_TRACKING
:
917 return "google_chrome_favicon_tracking";
918 case SUPERVISED_USER_SETTINGS
:
919 return "google_chrome_managed_user_settings";
920 case SUPERVISED_USERS
:
921 return "google_chrome_managed_users";
922 case SUPERVISED_USER_SHARED_SETTINGS
:
923 return "google_chrome_managed_user_shared_settings";
924 case SUPERVISED_USER_WHITELISTS
:
925 return "google_chrome_managed_user_whitelists";
927 return "google_chrome_articles";
928 case WIFI_CREDENTIALS
:
929 return "google_chrome_wifi_credentials";
931 return std::string();
935 NOTREACHED() << "No known extension for model type.";
939 // TODO(akalin): Figure out a better way to do these mappings.
940 // Note: Do not include proxy types in this list. They should never receive
941 // or trigger notifications.
943 const char kBookmarkNotificationType
[] = "BOOKMARK";
944 const char kPreferenceNotificationType
[] = "PREFERENCE";
945 const char kPasswordNotificationType
[] = "PASSWORD";
946 const char kAutofillNotificationType
[] = "AUTOFILL";
947 const char kThemeNotificationType
[] = "THEME";
948 const char kTypedUrlNotificationType
[] = "TYPED_URL";
949 const char kExtensionNotificationType
[] = "EXTENSION";
950 const char kExtensionSettingNotificationType
[] = "EXTENSION_SETTING";
951 const char kNigoriNotificationType
[] = "NIGORI";
952 const char kAppSettingNotificationType
[] = "APP_SETTING";
953 const char kAppNotificationType
[] = "APP";
954 const char kAppListNotificationType
[] = "APP_LIST";
955 const char kSearchEngineNotificationType
[] = "SEARCH_ENGINE";
956 const char kSessionNotificationType
[] = "SESSION";
957 const char kAutofillProfileNotificationType
[] = "AUTOFILL_PROFILE";
958 const char kAutofillWalletMetadataNotificationType
[] =
959 "AUTOFILL_WALLET_METADATA";
960 const char kAutofillWalletNotificationType
[] = "AUTOFILL_WALLET";
961 const char kAppNotificationNotificationType
[] = "APP_NOTIFICATION";
962 const char kHistoryDeleteDirectiveNotificationType
[] =
963 "HISTORY_DELETE_DIRECTIVE";
964 const char kSyncedNotificationType
[] = "SYNCED_NOTIFICATION";
965 const char kSyncedNotificationAppInfoType
[] = "SYNCED_NOTIFICATION_APP_INFO";
966 const char kDeviceInfoNotificationType
[] = "DEVICE_INFO";
967 const char kExperimentsNotificationType
[] = "EXPERIMENTS";
968 const char kPriorityPreferenceNotificationType
[] = "PRIORITY_PREFERENCE";
969 const char kDictionaryNotificationType
[] = "DICTIONARY";
970 const char kFaviconImageNotificationType
[] = "FAVICON_IMAGE";
971 const char kFaviconTrackingNotificationType
[] = "FAVICON_TRACKING";
972 const char kSupervisedUserSettingNotificationType
[] = "MANAGED_USER_SETTING";
973 const char kSupervisedUserNotificationType
[] = "MANAGED_USER";
974 const char kSupervisedUserSharedSettingNotificationType
[] =
975 "MANAGED_USER_SHARED_SETTING";
976 const char kSupervisedUserWhitelistNotificationType
[] =
977 "MANAGED_USER_WHITELIST";
978 const char kArticleNotificationType
[] = "ARTICLE";
979 const char kWifiCredentialNotificationType
[] = "WIFI_CREDENTIAL";
982 bool RealModelTypeToNotificationType(ModelType model_type
,
983 std::string
* notification_type
) {
984 switch (model_type
) {
986 *notification_type
= kBookmarkNotificationType
;
989 *notification_type
= kPreferenceNotificationType
;
992 *notification_type
= kPasswordNotificationType
;
995 *notification_type
= kAutofillNotificationType
;
998 *notification_type
= kThemeNotificationType
;
1001 *notification_type
= kTypedUrlNotificationType
;
1004 *notification_type
= kExtensionNotificationType
;
1007 *notification_type
= kNigoriNotificationType
;
1010 *notification_type
= kAppSettingNotificationType
;
1013 *notification_type
= kAppNotificationType
;
1016 *notification_type
= kAppListNotificationType
;
1018 case SEARCH_ENGINES
:
1019 *notification_type
= kSearchEngineNotificationType
;
1022 *notification_type
= kSessionNotificationType
;
1024 case AUTOFILL_PROFILE
:
1025 *notification_type
= kAutofillProfileNotificationType
;
1027 case AUTOFILL_WALLET_DATA
:
1028 *notification_type
= kAutofillWalletNotificationType
;
1030 case AUTOFILL_WALLET_METADATA
:
1031 *notification_type
= kAutofillWalletMetadataNotificationType
;
1033 case EXTENSION_SETTINGS
:
1034 *notification_type
= kExtensionSettingNotificationType
;
1036 case APP_NOTIFICATIONS
:
1037 *notification_type
= kAppNotificationNotificationType
;
1039 case HISTORY_DELETE_DIRECTIVES
:
1040 *notification_type
= kHistoryDeleteDirectiveNotificationType
;
1042 case SYNCED_NOTIFICATIONS
:
1043 *notification_type
= kSyncedNotificationType
;
1045 case SYNCED_NOTIFICATION_APP_INFO
:
1046 *notification_type
= kSyncedNotificationAppInfoType
;
1049 *notification_type
= kDeviceInfoNotificationType
;
1052 *notification_type
= kExperimentsNotificationType
;
1054 case PRIORITY_PREFERENCES
:
1055 *notification_type
= kPriorityPreferenceNotificationType
;
1058 *notification_type
= kDictionaryNotificationType
;
1060 case FAVICON_IMAGES
:
1061 *notification_type
= kFaviconImageNotificationType
;
1063 case FAVICON_TRACKING
:
1064 *notification_type
= kFaviconTrackingNotificationType
;
1066 case SUPERVISED_USER_SETTINGS
:
1067 *notification_type
= kSupervisedUserSettingNotificationType
;
1069 case SUPERVISED_USERS
:
1070 *notification_type
= kSupervisedUserNotificationType
;
1072 case SUPERVISED_USER_SHARED_SETTINGS
:
1073 *notification_type
= kSupervisedUserSharedSettingNotificationType
;
1075 case SUPERVISED_USER_WHITELISTS
:
1076 *notification_type
= kSupervisedUserWhitelistNotificationType
;
1079 *notification_type
= kArticleNotificationType
;
1081 case WIFI_CREDENTIALS
:
1082 *notification_type
= kWifiCredentialNotificationType
;
1087 notification_type
->clear();
1091 bool NotificationTypeToRealModelType(const std::string
& notification_type
,
1092 ModelType
* model_type
) {
1093 if (notification_type
== kBookmarkNotificationType
) {
1094 *model_type
= BOOKMARKS
;
1096 } else if (notification_type
== kPreferenceNotificationType
) {
1097 *model_type
= PREFERENCES
;
1099 } else if (notification_type
== kPasswordNotificationType
) {
1100 *model_type
= PASSWORDS
;
1102 } else if (notification_type
== kAutofillNotificationType
) {
1103 *model_type
= AUTOFILL
;
1105 } else if (notification_type
== kThemeNotificationType
) {
1106 *model_type
= THEMES
;
1108 } else if (notification_type
== kTypedUrlNotificationType
) {
1109 *model_type
= TYPED_URLS
;
1111 } else if (notification_type
== kExtensionNotificationType
) {
1112 *model_type
= EXTENSIONS
;
1114 } else if (notification_type
== kNigoriNotificationType
) {
1115 *model_type
= NIGORI
;
1117 } else if (notification_type
== kAppNotificationType
) {
1120 } else if (notification_type
== kAppListNotificationType
) {
1121 *model_type
= APP_LIST
;
1123 } else if (notification_type
== kSearchEngineNotificationType
) {
1124 *model_type
= SEARCH_ENGINES
;
1126 } else if (notification_type
== kSessionNotificationType
) {
1127 *model_type
= SESSIONS
;
1129 } else if (notification_type
== kAutofillProfileNotificationType
) {
1130 *model_type
= AUTOFILL_PROFILE
;
1132 } else if (notification_type
== kAutofillWalletNotificationType
) {
1133 *model_type
= AUTOFILL_WALLET_DATA
;
1135 } else if (notification_type
== kAutofillWalletMetadataNotificationType
) {
1136 *model_type
= AUTOFILL_WALLET_METADATA
;
1138 } else if (notification_type
== kAppSettingNotificationType
) {
1139 *model_type
= APP_SETTINGS
;
1141 } else if (notification_type
== kExtensionSettingNotificationType
) {
1142 *model_type
= EXTENSION_SETTINGS
;
1144 } else if (notification_type
== kAppNotificationNotificationType
) {
1145 *model_type
= APP_NOTIFICATIONS
;
1147 } else if (notification_type
== kHistoryDeleteDirectiveNotificationType
) {
1148 *model_type
= HISTORY_DELETE_DIRECTIVES
;
1150 } else if (notification_type
== kSyncedNotificationType
) {
1151 *model_type
= SYNCED_NOTIFICATIONS
;
1153 } else if (notification_type
== kSyncedNotificationAppInfoType
) {
1154 *model_type
= SYNCED_NOTIFICATION_APP_INFO
;
1156 } else if (notification_type
== kDeviceInfoNotificationType
) {
1157 *model_type
= DEVICE_INFO
;
1159 } else if (notification_type
== kExperimentsNotificationType
) {
1160 *model_type
= EXPERIMENTS
;
1162 } else if (notification_type
== kPriorityPreferenceNotificationType
) {
1163 *model_type
= PRIORITY_PREFERENCES
;
1165 } else if (notification_type
== kDictionaryNotificationType
) {
1166 *model_type
= DICTIONARY
;
1168 } else if (notification_type
== kFaviconImageNotificationType
) {
1169 *model_type
= FAVICON_IMAGES
;
1171 } else if (notification_type
== kFaviconTrackingNotificationType
) {
1172 *model_type
= FAVICON_TRACKING
;
1174 } else if (notification_type
== kSupervisedUserSettingNotificationType
) {
1175 *model_type
= SUPERVISED_USER_SETTINGS
;
1177 } else if (notification_type
== kSupervisedUserNotificationType
) {
1178 *model_type
= SUPERVISED_USERS
;
1180 } else if (notification_type
==
1181 kSupervisedUserSharedSettingNotificationType
) {
1182 *model_type
= SUPERVISED_USER_SHARED_SETTINGS
;
1184 } else if (notification_type
== kSupervisedUserWhitelistNotificationType
) {
1185 *model_type
= SUPERVISED_USER_WHITELISTS
;
1187 } else if (notification_type
== kArticleNotificationType
) {
1188 *model_type
= ARTICLES
;
1190 } else if (notification_type
== kWifiCredentialNotificationType
) {
1191 *model_type
= WIFI_CREDENTIALS
;
1194 *model_type
= UNSPECIFIED
;
1198 bool IsRealDataType(ModelType model_type
) {
1199 return model_type
>= FIRST_REAL_MODEL_TYPE
&& model_type
< MODEL_TYPE_COUNT
;
1202 bool IsProxyType(ModelType model_type
) {
1203 return model_type
>= FIRST_PROXY_TYPE
&& model_type
<= LAST_PROXY_TYPE
;
1206 bool IsActOnceDataType(ModelType model_type
) {
1207 return model_type
== HISTORY_DELETE_DIRECTIVES
;
1210 bool IsTypeWithServerGeneratedRoot(ModelType model_type
) {
1211 return model_type
== BOOKMARKS
|| model_type
== NIGORI
;
1214 bool IsTypeWithClientGeneratedRoot(ModelType model_type
) {
1215 return IsRealDataType(model_type
) &&
1216 !IsTypeWithServerGeneratedRoot(model_type
);
1219 bool TypeSupportsHierarchy(ModelType model_type
) {
1220 // TODO(stanisc): crbug/438313: Should this also include TOP_LEVEL_FOLDER?
1221 return model_type
== BOOKMARKS
;
1224 bool TypeSupportsOrdering(ModelType model_type
) {
1225 return model_type
== BOOKMARKS
;
1228 } // namespace syncer