Add tests to verify accelerators properly work on constrained window.
[chromium-blink-merge.git] / sync / syncable / model_type.cc
bloba6ee40957e0b5bbc3bdf51838dc1d89d7e1f2abb
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/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 void AddDefaultFieldValue(ModelType datatype,
29 sync_pb::EntitySpecifics* specifics) {
30 switch (datatype) {
31 case BOOKMARKS:
32 specifics->mutable_bookmark();
33 break;
34 case PASSWORDS:
35 specifics->mutable_password();
36 break;
37 case PREFERENCES:
38 specifics->mutable_preference();
39 break;
40 case AUTOFILL:
41 specifics->mutable_autofill();
42 break;
43 case AUTOFILL_PROFILE:
44 specifics->mutable_autofill_profile();
45 break;
46 case THEMES:
47 specifics->mutable_theme();
48 break;
49 case TYPED_URLS:
50 specifics->mutable_typed_url();
51 break;
52 case EXTENSIONS:
53 specifics->mutable_extension();
54 break;
55 case NIGORI:
56 specifics->mutable_nigori();
57 break;
58 case SEARCH_ENGINES:
59 specifics->mutable_search_engine();
60 break;
61 case SESSIONS:
62 specifics->mutable_session();
63 break;
64 case APPS:
65 specifics->mutable_app();
66 break;
67 case APP_SETTINGS:
68 specifics->mutable_app_setting();
69 break;
70 case EXTENSION_SETTINGS:
71 specifics->mutable_extension_setting();
72 break;
73 case APP_NOTIFICATIONS:
74 specifics->mutable_app_notification();
75 break;
76 case HISTORY_DELETE_DIRECTIVES:
77 specifics->mutable_history_delete_directive();
78 break;
79 case SYNCED_NOTIFICATIONS:
80 specifics->mutable_synced_notification();
81 break;
82 case DEVICE_INFO:
83 specifics->mutable_device_info();
84 break;
85 case EXPERIMENTS:
86 specifics->mutable_experiments();
87 break;
88 default:
89 NOTREACHED() << "No known extension for model type.";
93 ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) {
94 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
95 ModelType model_type = ModelTypeFromInt(i);
96 if (GetSpecificsFieldNumberFromModelType(model_type) == field_number)
97 return model_type;
99 return UNSPECIFIED;
102 int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
103 switch (model_type) {
104 case BOOKMARKS:
105 return sync_pb::EntitySpecifics::kBookmarkFieldNumber;
106 break;
107 case PASSWORDS:
108 return sync_pb::EntitySpecifics::kPasswordFieldNumber;
109 break;
110 case PREFERENCES:
111 return sync_pb::EntitySpecifics::kPreferenceFieldNumber;
112 break;
113 case AUTOFILL:
114 return sync_pb::EntitySpecifics::kAutofillFieldNumber;
115 break;
116 case AUTOFILL_PROFILE:
117 return sync_pb::EntitySpecifics::kAutofillProfileFieldNumber;
118 break;
119 case THEMES:
120 return sync_pb::EntitySpecifics::kThemeFieldNumber;
121 break;
122 case TYPED_URLS:
123 return sync_pb::EntitySpecifics::kTypedUrlFieldNumber;
124 break;
125 case EXTENSIONS:
126 return sync_pb::EntitySpecifics::kExtensionFieldNumber;
127 break;
128 case NIGORI:
129 return sync_pb::EntitySpecifics::kNigoriFieldNumber;
130 break;
131 case SEARCH_ENGINES:
132 return sync_pb::EntitySpecifics::kSearchEngineFieldNumber;
133 break;
134 case SESSIONS:
135 return sync_pb::EntitySpecifics::kSessionFieldNumber;
136 break;
137 case APPS:
138 return sync_pb::EntitySpecifics::kAppFieldNumber;
139 break;
140 case APP_SETTINGS:
141 return sync_pb::EntitySpecifics::kAppSettingFieldNumber;
142 break;
143 case EXTENSION_SETTINGS:
144 return sync_pb::EntitySpecifics::kExtensionSettingFieldNumber;
145 break;
146 case APP_NOTIFICATIONS:
147 return sync_pb::EntitySpecifics::kAppNotificationFieldNumber;
148 break;
149 case HISTORY_DELETE_DIRECTIVES:
150 return sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber;
151 case SYNCED_NOTIFICATIONS:
152 return sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber;
153 case DEVICE_INFO:
154 return sync_pb::EntitySpecifics::kDeviceInfoFieldNumber;
155 break;
156 case EXPERIMENTS:
157 return sync_pb::EntitySpecifics::kExperimentsFieldNumber;
158 break;
159 default:
160 NOTREACHED() << "No known extension for model type.";
161 return 0;
163 NOTREACHED() << "Needed for linux_keep_shadow_stacks because of "
164 << "http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20681";
165 return 0;
168 FullModelTypeSet ToFullModelTypeSet(ModelTypeSet in) {
169 FullModelTypeSet out;
170 for (ModelTypeSet::Iterator i = in.First(); i.Good(); i.Inc()) {
171 out.Put(i.Get());
173 return out;
176 // Note: keep this consistent with GetModelType in entry.cc!
177 ModelType GetModelType(const sync_pb::SyncEntity& sync_entity) {
178 DCHECK(!IsRoot(sync_entity)); // Root shouldn't ever go over the wire.
180 if (sync_entity.deleted())
181 return UNSPECIFIED;
183 // Backwards compatibility with old (pre-specifics) protocol.
184 if (sync_entity.has_bookmarkdata())
185 return BOOKMARKS;
187 ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics());
188 if (specifics_type != UNSPECIFIED)
189 return specifics_type;
191 // Loose check for server-created top-level folders that aren't
192 // bound to a particular model type.
193 if (!sync_entity.server_defined_unique_tag().empty() &&
194 IsFolder(sync_entity)) {
195 return TOP_LEVEL_FOLDER;
198 // This is an item of a datatype we can't understand. Maybe it's
199 // from the future? Either we mis-encoded the object, or the
200 // server sent us entries it shouldn't have.
201 NOTREACHED() << "Unknown datatype in sync proto.";
202 return UNSPECIFIED;
205 ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
206 if (specifics.has_bookmark())
207 return BOOKMARKS;
209 if (specifics.has_password())
210 return PASSWORDS;
212 if (specifics.has_preference())
213 return PREFERENCES;
215 if (specifics.has_autofill())
216 return AUTOFILL;
218 if (specifics.has_autofill_profile())
219 return AUTOFILL_PROFILE;
221 if (specifics.has_theme())
222 return THEMES;
224 if (specifics.has_typed_url())
225 return TYPED_URLS;
227 if (specifics.has_extension())
228 return EXTENSIONS;
230 if (specifics.has_nigori())
231 return NIGORI;
233 if (specifics.has_app())
234 return APPS;
236 if (specifics.has_search_engine())
237 return SEARCH_ENGINES;
239 if (specifics.has_session())
240 return SESSIONS;
242 if (specifics.has_app_setting())
243 return APP_SETTINGS;
245 if (specifics.has_extension_setting())
246 return EXTENSION_SETTINGS;
248 if (specifics.has_app_notification())
249 return APP_NOTIFICATIONS;
251 if (specifics.has_history_delete_directive())
252 return HISTORY_DELETE_DIRECTIVES;
254 if (specifics.has_synced_notification())
255 return SYNCED_NOTIFICATIONS;
257 if (specifics.has_device_info())
258 return DEVICE_INFO;
260 if (specifics.has_experiments())
261 return EXPERIMENTS;
263 return UNSPECIFIED;
266 bool ShouldMaintainPosition(ModelType model_type) {
267 return model_type == BOOKMARKS;
270 ModelTypeSet UserTypes() {
271 ModelTypeSet set;
272 for (int i = FIRST_USER_MODEL_TYPE; i <= LAST_USER_MODEL_TYPE; ++i) {
273 set.Put(ModelTypeFromInt(i));
275 return set;
278 ModelTypeSet EncryptableUserTypes() {
279 ModelTypeSet encryptable_user_types = UserTypes();
280 // We never encrypt history delete directives.
281 encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
282 // Synced notifications are not encrypted since the server must see changes.
283 encryptable_user_types.Remove(SYNCED_NOTIFICATIONS);
284 return encryptable_user_types;
287 ModelTypeSet ControlTypes() {
288 ModelTypeSet set;
289 for (int i = FIRST_CONTROL_MODEL_TYPE; i <= LAST_CONTROL_MODEL_TYPE; ++i) {
290 set.Put(ModelTypeFromInt(i));
293 return set;
296 bool IsControlType(ModelType model_type) {
297 return ControlTypes().Has(model_type);
300 const char* ModelTypeToString(ModelType model_type) {
301 // This is used in serialization routines as well as for displaying debug
302 // information. Do not attempt to change these string values unless you know
303 // what you're doing.
304 switch (model_type) {
305 case TOP_LEVEL_FOLDER:
306 return "Top Level Folder";
307 case UNSPECIFIED:
308 return "Unspecified";
309 case BOOKMARKS:
310 return "Bookmarks";
311 case PREFERENCES:
312 return "Preferences";
313 case PASSWORDS:
314 return "Passwords";
315 case AUTOFILL:
316 return "Autofill";
317 case THEMES:
318 return "Themes";
319 case TYPED_URLS:
320 return "Typed URLs";
321 case EXTENSIONS:
322 return "Extensions";
323 case NIGORI:
324 return "Encryption keys";
325 case SEARCH_ENGINES:
326 return "Search Engines";
327 case SESSIONS:
328 return "Sessions";
329 case APPS:
330 return "Apps";
331 case AUTOFILL_PROFILE:
332 return "Autofill Profiles";
333 case APP_SETTINGS:
334 return "App settings";
335 case EXTENSION_SETTINGS:
336 return "Extension settings";
337 case APP_NOTIFICATIONS:
338 return "App Notifications";
339 case HISTORY_DELETE_DIRECTIVES:
340 return "History Delete Directives";
341 case SYNCED_NOTIFICATIONS:
342 return "Synced Notifications";
343 case DEVICE_INFO:
344 return "Device Info";
345 case EXPERIMENTS:
346 return "Experiments";
347 default:
348 break;
350 NOTREACHED() << "No known extension for model type.";
351 return "INVALID";
354 StringValue* ModelTypeToValue(ModelType model_type) {
355 if (model_type >= FIRST_REAL_MODEL_TYPE) {
356 return Value::CreateStringValue(ModelTypeToString(model_type));
357 } else if (model_type == TOP_LEVEL_FOLDER) {
358 return Value::CreateStringValue("Top-level folder");
359 } else if (model_type == UNSPECIFIED) {
360 return Value::CreateStringValue("Unspecified");
362 NOTREACHED();
363 return Value::CreateStringValue("");
366 ModelType ModelTypeFromValue(const Value& value) {
367 if (value.IsType(Value::TYPE_STRING)) {
368 std::string result;
369 CHECK(value.GetAsString(&result));
370 return ModelTypeFromString(result);
371 } else if (value.IsType(Value::TYPE_INTEGER)) {
372 int result;
373 CHECK(value.GetAsInteger(&result));
374 return ModelTypeFromInt(result);
375 } else {
376 NOTREACHED() << "Unsupported value type: " << value.GetType();
377 return UNSPECIFIED;
381 ModelType ModelTypeFromString(const std::string& model_type_string) {
382 if (model_type_string == "Bookmarks")
383 return BOOKMARKS;
384 else if (model_type_string == "Preferences")
385 return PREFERENCES;
386 else if (model_type_string == "Passwords")
387 return PASSWORDS;
388 else if (model_type_string == "Autofill")
389 return AUTOFILL;
390 else if (model_type_string == "Autofill Profiles")
391 return AUTOFILL_PROFILE;
392 else if (model_type_string == "Themes")
393 return THEMES;
394 else if (model_type_string == "Typed URLs")
395 return TYPED_URLS;
396 else if (model_type_string == "Extensions")
397 return EXTENSIONS;
398 else if (model_type_string == "Encryption keys")
399 return NIGORI;
400 else if (model_type_string == "Search Engines")
401 return SEARCH_ENGINES;
402 else if (model_type_string == "Sessions")
403 return SESSIONS;
404 else if (model_type_string == "Apps")
405 return APPS;
406 else if (model_type_string == "App settings")
407 return APP_SETTINGS;
408 else if (model_type_string == "Extension settings")
409 return EXTENSION_SETTINGS;
410 else if (model_type_string == "App Notifications")
411 return APP_NOTIFICATIONS;
412 else if (model_type_string == "History Delete Directives")
413 return HISTORY_DELETE_DIRECTIVES;
414 else if (model_type_string == "Synced Notifications")
415 return SYNCED_NOTIFICATIONS;
416 else if (model_type_string == "Device Info")
417 return DEVICE_INFO;
418 else if (model_type_string == "Experiments")
419 return EXPERIMENTS;
420 else
421 NOTREACHED() << "No known model type corresponding to "
422 << model_type_string << ".";
423 return UNSPECIFIED;
426 std::string ModelTypeSetToString(ModelTypeSet model_types) {
427 std::string result;
428 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
429 if (!result.empty()) {
430 result += ", ";
432 result += ModelTypeToString(it.Get());
434 return result;
437 base::ListValue* ModelTypeSetToValue(ModelTypeSet model_types) {
438 ListValue* value = new ListValue();
439 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) {
440 value->Append(
441 Value::CreateStringValue(ModelTypeToString(it.Get())));
443 return value;
446 ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value) {
447 ModelTypeSet result;
448 for (ListValue::const_iterator i = value.begin(); i != value.end(); ++i) {
449 result.Put(ModelTypeFromValue(**i));
451 return result;
454 // TODO(zea): remove all hardcoded tags in model associators and have them use
455 // this instead.
456 std::string ModelTypeToRootTag(ModelType type) {
457 switch (type) {
458 case BOOKMARKS:
459 return "google_chrome_bookmarks";
460 case PREFERENCES:
461 return "google_chrome_preferences";
462 case PASSWORDS:
463 return "google_chrome_passwords";
464 case AUTOFILL:
465 return "google_chrome_autofill";
466 case THEMES:
467 return "google_chrome_themes";
468 case TYPED_URLS:
469 return "google_chrome_typed_urls";
470 case EXTENSIONS:
471 return "google_chrome_extensions";
472 case NIGORI:
473 return "google_chrome_nigori";
474 case SEARCH_ENGINES:
475 return "google_chrome_search_engines";
476 case SESSIONS:
477 return "google_chrome_sessions";
478 case APPS:
479 return "google_chrome_apps";
480 case AUTOFILL_PROFILE:
481 return "google_chrome_autofill_profiles";
482 case APP_SETTINGS:
483 return "google_chrome_app_settings";
484 case EXTENSION_SETTINGS:
485 return "google_chrome_extension_settings";
486 case APP_NOTIFICATIONS:
487 return "google_chrome_app_notifications";
488 case HISTORY_DELETE_DIRECTIVES:
489 return "google_chrome_history_delete_directives";
490 case SYNCED_NOTIFICATIONS:
491 return "google_chrome_synced_notifications";
492 case DEVICE_INFO:
493 return "google_chrome_device_info";
494 case EXPERIMENTS:
495 return "google_chrome_experiments";
496 default:
497 break;
499 NOTREACHED() << "No known extension for model type.";
500 return "INVALID";
503 // TODO(akalin): Figure out a better way to do these mappings.
505 namespace {
506 const char kBookmarkNotificationType[] = "BOOKMARK";
507 const char kPreferenceNotificationType[] = "PREFERENCE";
508 const char kPasswordNotificationType[] = "PASSWORD";
509 const char kAutofillNotificationType[] = "AUTOFILL";
510 const char kThemeNotificationType[] = "THEME";
511 const char kTypedUrlNotificationType[] = "TYPED_URL";
512 const char kExtensionNotificationType[] = "EXTENSION";
513 const char kExtensionSettingNotificationType[] = "EXTENSION_SETTING";
514 const char kNigoriNotificationType[] = "NIGORI";
515 const char kAppSettingNotificationType[] = "APP_SETTING";
516 const char kAppNotificationType[] = "APP";
517 const char kSearchEngineNotificationType[] = "SEARCH_ENGINE";
518 const char kSessionNotificationType[] = "SESSION";
519 const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE";
520 const char kAppNotificationNotificationType[] = "APP_NOTIFICATION";
521 const char kHistoryDeleteDirectiveNotificationType[] =
522 "HISTORY_DELETE_DIRECTIVE";
523 const char kSyncedNotificationType[] = "SYNCED_NOTIFICATION";
524 const char kDeviceInfoNotificationType[] = "DEVICE_INFO";
525 const char kExperimentsNotificationType[] = "EXPERIMENTS";
526 } // namespace
528 bool RealModelTypeToNotificationType(ModelType model_type,
529 std::string* notification_type) {
530 switch (model_type) {
531 case BOOKMARKS:
532 *notification_type = kBookmarkNotificationType;
533 return true;
534 case PREFERENCES:
535 *notification_type = kPreferenceNotificationType;
536 return true;
537 case PASSWORDS:
538 *notification_type = kPasswordNotificationType;
539 return true;
540 case AUTOFILL:
541 *notification_type = kAutofillNotificationType;
542 return true;
543 case THEMES:
544 *notification_type = kThemeNotificationType;
545 return true;
546 case TYPED_URLS:
547 *notification_type = kTypedUrlNotificationType;
548 return true;
549 case EXTENSIONS:
550 *notification_type = kExtensionNotificationType;
551 return true;
552 case NIGORI:
553 *notification_type = kNigoriNotificationType;
554 return true;
555 case APP_SETTINGS:
556 *notification_type = kAppSettingNotificationType;
557 return true;
558 case APPS:
559 *notification_type = kAppNotificationType;
560 return true;
561 case SEARCH_ENGINES:
562 *notification_type = kSearchEngineNotificationType;
563 return true;
564 case SESSIONS:
565 *notification_type = kSessionNotificationType;
566 return true;
567 case AUTOFILL_PROFILE:
568 *notification_type = kAutofillProfileNotificationType;
569 return true;
570 case EXTENSION_SETTINGS:
571 *notification_type = kExtensionSettingNotificationType;
572 return true;
573 case APP_NOTIFICATIONS:
574 *notification_type = kAppNotificationNotificationType;
575 return true;
576 case HISTORY_DELETE_DIRECTIVES:
577 *notification_type = kHistoryDeleteDirectiveNotificationType;
578 case SYNCED_NOTIFICATIONS:
579 *notification_type = kSyncedNotificationType;
580 case DEVICE_INFO:
581 *notification_type = kDeviceInfoNotificationType;
582 return true;
583 case EXPERIMENTS:
584 *notification_type = kExperimentsNotificationType;
585 return true;
586 default:
587 break;
589 notification_type->clear();
590 return false;
593 bool NotificationTypeToRealModelType(const std::string& notification_type,
594 ModelType* model_type) {
595 if (notification_type == kBookmarkNotificationType) {
596 *model_type = BOOKMARKS;
597 return true;
598 } else if (notification_type == kPreferenceNotificationType) {
599 *model_type = PREFERENCES;
600 return true;
601 } else if (notification_type == kPasswordNotificationType) {
602 *model_type = PASSWORDS;
603 return true;
604 } else if (notification_type == kAutofillNotificationType) {
605 *model_type = AUTOFILL;
606 return true;
607 } else if (notification_type == kThemeNotificationType) {
608 *model_type = THEMES;
609 return true;
610 } else if (notification_type == kTypedUrlNotificationType) {
611 *model_type = TYPED_URLS;
612 return true;
613 } else if (notification_type == kExtensionNotificationType) {
614 *model_type = EXTENSIONS;
615 return true;
616 } else if (notification_type == kNigoriNotificationType) {
617 *model_type = NIGORI;
618 return true;
619 } else if (notification_type == kAppNotificationType) {
620 *model_type = APPS;
621 return true;
622 } else if (notification_type == kSearchEngineNotificationType) {
623 *model_type = SEARCH_ENGINES;
624 return true;
625 } else if (notification_type == kSessionNotificationType) {
626 *model_type = SESSIONS;
627 return true;
628 } else if (notification_type == kAutofillProfileNotificationType) {
629 *model_type = AUTOFILL_PROFILE;
630 return true;
631 } else if (notification_type == kAppSettingNotificationType) {
632 *model_type = APP_SETTINGS;
633 return true;
634 } else if (notification_type == kExtensionSettingNotificationType) {
635 *model_type = EXTENSION_SETTINGS;
636 return true;
637 } else if (notification_type == kAppNotificationNotificationType) {
638 *model_type = APP_NOTIFICATIONS;
639 return true;
640 } else if (notification_type == kHistoryDeleteDirectiveNotificationType) {
641 *model_type = HISTORY_DELETE_DIRECTIVES;
642 } else if (notification_type == kSyncedNotificationType) {
643 *model_type = SYNCED_NOTIFICATIONS;
644 } else if (notification_type == kDeviceInfoNotificationType) {
645 *model_type = DEVICE_INFO;;
646 return true;
648 *model_type = UNSPECIFIED;
649 return false;
652 bool IsRealDataType(ModelType model_type) {
653 return model_type >= FIRST_REAL_MODEL_TYPE && model_type < MODEL_TYPE_COUNT;
656 } // namespace syncer