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. 4 5 #include "sync/internal_api/public/base/model_type.h" 6 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" 25 26 namespace syncer { 27 28 void AddDefaultFieldValue(ModelType datatype, 29 sync_pb::EntitySpecifics* specifics) { 30 if (!ProtocolTypes().Has(datatype)) { 31 NOTREACHED() << "Only protocol types have field values."; 32 return; 33 } 34 switch (datatype) { 35 case BOOKMARKS: 36 specifics->mutable_bookmark(); 37 break; 38 case PASSWORDS: 39 specifics->mutable_password(); 40 break; 41 case PREFERENCES: 42 specifics->mutable_preference(); 43 break; 44 case AUTOFILL: 45 specifics->mutable_autofill(); 46 break; 47 case AUTOFILL_PROFILE: 48 specifics->mutable_autofill_profile(); 49 break; 50 case THEMES: 51 specifics->mutable_theme(); 52 break; 53 case TYPED_URLS: 54 specifics->mutable_typed_url(); 55 break; 56 case EXTENSIONS: 57 specifics->mutable_extension(); 58 break; 59 case NIGORI: 60 specifics->mutable_nigori(); 61 break; 62 case SEARCH_ENGINES: 63 specifics->mutable_search_engine(); 64 break; 65 case SESSIONS: 66 specifics->mutable_session(); 67 break; 68 case APPS: 69 specifics->mutable_app(); 70 break; 71 case APP_SETTINGS: 72 specifics->mutable_app_setting(); 73 break; 74 case EXTENSION_SETTINGS: 75 specifics->mutable_extension_setting(); 76 break; 77 case APP_NOTIFICATIONS: 78 specifics->mutable_app_notification(); 79 break; 80 case HISTORY_DELETE_DIRECTIVES: 81 specifics->mutable_history_delete_directive(); 82 break; 83 case SYNCED_NOTIFICATIONS: 84 specifics->mutable_synced_notification(); 85 break; 86 case DEVICE_INFO: 87 specifics->mutable_device_info(); 88 break; 89 case EXPERIMENTS: 90 specifics->mutable_experiments(); 91 break; 92 case PRIORITY_PREFERENCES: 93 specifics->mutable_priority_preference(); 94 break; 95 case DICTIONARY: 96 specifics->mutable_dictionary(); 97 break; 98 case FAVICON_IMAGES: 99 specifics->mutable_favicon_image(); 100 break; 101 case FAVICON_TRACKING: 102 specifics->mutable_favicon_tracking(); 103 break; 104 case MANAGED_USER_SETTINGS: 105 specifics->mutable_managed_user_setting(); 106 break; 107 case MANAGED_USERS: 108 specifics->mutable_managed_user(); 109 break; 110 default: 111 NOTREACHED() << "No known extension for model type."; 112 } 113 } 114 115 ModelType GetModelTypeFromSpecificsFieldNumber(int field_number) { 116 ModelTypeSet protocol_types = ProtocolTypes(); 117 for (ModelTypeSet::Iterator iter = protocol_types.First(); iter.Good(); 118 iter.Inc()) { 119 if (GetSpecificsFieldNumberFromModelType(iter.Get()) == field_number) 120 return iter.Get(); 121 } 122 return UNSPECIFIED; 123 } 124 125 int GetSpecificsFieldNumberFromModelType(ModelType model_type) { 126 if (!ProtocolTypes().Has(model_type)) { 127 NOTREACHED() << "Only protocol types have field values."; 128 return 0; 129 } 130 switch (model_type) { 131 case BOOKMARKS: 132 return sync_pb::EntitySpecifics::kBookmarkFieldNumber; 133 break; 134 case PASSWORDS: 135 return sync_pb::EntitySpecifics::kPasswordFieldNumber; 136 break; 137 case PREFERENCES: 138 return sync_pb::EntitySpecifics::kPreferenceFieldNumber; 139 break; 140 case AUTOFILL: 141 return sync_pb::EntitySpecifics::kAutofillFieldNumber; 142 break; 143 case AUTOFILL_PROFILE: 144 return sync_pb::EntitySpecifics::kAutofillProfileFieldNumber; 145 break; 146 case THEMES: 147 return sync_pb::EntitySpecifics::kThemeFieldNumber; 148 break; 149 case TYPED_URLS: 150 return sync_pb::EntitySpecifics::kTypedUrlFieldNumber; 151 break; 152 case EXTENSIONS: 153 return sync_pb::EntitySpecifics::kExtensionFieldNumber; 154 break; 155 case NIGORI: 156 return sync_pb::EntitySpecifics::kNigoriFieldNumber; 157 break; 158 case SEARCH_ENGINES: 159 return sync_pb::EntitySpecifics::kSearchEngineFieldNumber; 160 break; 161 case SESSIONS: 162 return sync_pb::EntitySpecifics::kSessionFieldNumber; 163 break; 164 case APPS: 165 return sync_pb::EntitySpecifics::kAppFieldNumber; 166 break; 167 case APP_SETTINGS: 168 return sync_pb::EntitySpecifics::kAppSettingFieldNumber; 169 break; 170 case EXTENSION_SETTINGS: 171 return sync_pb::EntitySpecifics::kExtensionSettingFieldNumber; 172 break; 173 case APP_NOTIFICATIONS: 174 return sync_pb::EntitySpecifics::kAppNotificationFieldNumber; 175 break; 176 case HISTORY_DELETE_DIRECTIVES: 177 return sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber; 178 case SYNCED_NOTIFICATIONS: 179 return sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber; 180 case DEVICE_INFO: 181 return sync_pb::EntitySpecifics::kDeviceInfoFieldNumber; 182 break; 183 case EXPERIMENTS: 184 return sync_pb::EntitySpecifics::kExperimentsFieldNumber; 185 break; 186 case PRIORITY_PREFERENCES: 187 return sync_pb::EntitySpecifics::kPriorityPreferenceFieldNumber; 188 break; 189 case DICTIONARY: 190 return sync_pb::EntitySpecifics::kDictionaryFieldNumber; 191 break; 192 case FAVICON_IMAGES: 193 return sync_pb::EntitySpecifics::kFaviconImageFieldNumber; 194 case FAVICON_TRACKING: 195 return sync_pb::EntitySpecifics::kFaviconTrackingFieldNumber; 196 case MANAGED_USER_SETTINGS: 197 return sync_pb::EntitySpecifics::kManagedUserSettingFieldNumber; 198 case MANAGED_USERS: 199 return sync_pb::EntitySpecifics::kManagedUserFieldNumber; 200 default: 201 NOTREACHED() << "No known extension for model type."; 202 return 0; 203 } 204 NOTREACHED() << "Needed for linux_keep_shadow_stacks because of " 205 << "http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20681"; 206 return 0; 207 } 208 209 FullModelTypeSet ToFullModelTypeSet(ModelTypeSet in) { 210 FullModelTypeSet out; 211 for (ModelTypeSet::Iterator i = in.First(); i.Good(); i.Inc()) { 212 out.Put(i.Get()); 213 } 214 return out; 215 } 216 217 // Note: keep this consistent with GetModelType in entry.cc! 218 ModelType GetModelType(const sync_pb::SyncEntity& sync_entity) { 219 DCHECK(!IsRoot(sync_entity)); // Root shouldn't ever go over the wire. 220 221 if (sync_entity.deleted()) 222 return UNSPECIFIED; 223 224 // Backwards compatibility with old (pre-specifics) protocol. 225 if (sync_entity.has_bookmarkdata()) 226 return BOOKMARKS; 227 228 ModelType specifics_type = GetModelTypeFromSpecifics(sync_entity.specifics()); 229 if (specifics_type != UNSPECIFIED) 230 return specifics_type; 231 232 // Loose check for server-created top-level folders that aren't 233 // bound to a particular model type. 234 if (!sync_entity.server_defined_unique_tag().empty() && 235 IsFolder(sync_entity)) { 236 return TOP_LEVEL_FOLDER; 237 } 238 239 // This is an item of a datatype we can't understand. Maybe it's 240 // from the future? Either we mis-encoded the object, or the 241 // server sent us entries it shouldn't have. 242 NOTREACHED() << "Unknown datatype in sync proto."; 243 return UNSPECIFIED; 244 } 245 246 ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) { 247 if (specifics.has_bookmark()) 248 return BOOKMARKS; 249 250 if (specifics.has_password()) 251 return PASSWORDS; 252 253 if (specifics.has_preference()) 254 return PREFERENCES; 255 256 if (specifics.has_autofill()) 257 return AUTOFILL; 258 259 if (specifics.has_autofill_profile()) 260 return AUTOFILL_PROFILE; 261 262 if (specifics.has_theme()) 263 return THEMES; 264 265 if (specifics.has_typed_url()) 266 return TYPED_URLS; 267 268 if (specifics.has_extension()) 269 return EXTENSIONS; 270 271 if (specifics.has_nigori()) 272 return NIGORI; 273 274 if (specifics.has_app()) 275 return APPS; 276 277 if (specifics.has_search_engine()) 278 return SEARCH_ENGINES; 279 280 if (specifics.has_session()) 281 return SESSIONS; 282 283 if (specifics.has_app_setting()) 284 return APP_SETTINGS; 285 286 if (specifics.has_extension_setting()) 287 return EXTENSION_SETTINGS; 288 289 if (specifics.has_app_notification()) 290 return APP_NOTIFICATIONS; 291 292 if (specifics.has_history_delete_directive()) 293 return HISTORY_DELETE_DIRECTIVES; 294 295 if (specifics.has_synced_notification()) 296 return SYNCED_NOTIFICATIONS; 297 298 if (specifics.has_device_info()) 299 return DEVICE_INFO; 300 301 if (specifics.has_experiments()) 302 return EXPERIMENTS; 303 304 if (specifics.has_priority_preference()) 305 return PRIORITY_PREFERENCES; 306 307 if (specifics.has_dictionary()) 308 return DICTIONARY; 309 310 if (specifics.has_favicon_image()) 311 return FAVICON_IMAGES; 312 313 if (specifics.has_favicon_tracking()) 314 return FAVICON_TRACKING; 315 316 if (specifics.has_managed_user_setting()) 317 return MANAGED_USER_SETTINGS; 318 319 if (specifics.has_managed_user()) 320 return MANAGED_USERS; 321 322 return UNSPECIFIED; 323 } 324 325 ModelTypeSet ProtocolTypes() { 326 ModelTypeSet set = ModelTypeSet::All(); 327 set.RemoveAll(ProxyTypes()); 328 return set; 329 } 330 331 ModelTypeSet UserTypes() { 332 ModelTypeSet set; 333 // TODO(sync): We should be able to build the actual enumset's internal 334 // bitset value here at compile time, rather than performing an iteration 335 // every time. 336 for (int i = FIRST_USER_MODEL_TYPE; i <= LAST_USER_MODEL_TYPE; ++i) { 337 set.Put(ModelTypeFromInt(i)); 338 } 339 return set; 340 } 341 342 ModelTypeSet UserSelectableTypes() { 343 ModelTypeSet set; 344 // Although the order doesn't technically matter here, it's clearer to keep 345 // these in the same order as their definition in the ModelType enum. 346 set.Put(BOOKMARKS); 347 set.Put(PREFERENCES); 348 set.Put(PASSWORDS); 349 set.Put(AUTOFILL); 350 set.Put(THEMES); 351 set.Put(TYPED_URLS); 352 set.Put(EXTENSIONS); 353 set.Put(APPS); 354 set.Put(PROXY_TABS); 355 return set; 356 } 357 358 bool IsUserSelectableType(ModelType model_type) { 359 return UserSelectableTypes().Has(model_type); 360 } 361 362 ModelTypeSet EncryptableUserTypes() { 363 ModelTypeSet encryptable_user_types = UserTypes(); 364 // We never encrypt history delete directives. 365 encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES); 366 // Synced notifications are not encrypted since the server must see changes. 367 encryptable_user_types.Remove(SYNCED_NOTIFICATIONS); 368 // Priority preferences are not encrypted because they might be synced before 369 // encryption is ready. 370 encryptable_user_types.Remove(PRIORITY_PREFERENCES); 371 // Managed user settings are not encrypted since they are set server-side. 372 encryptable_user_types.Remove(MANAGED_USER_SETTINGS); 373 // Managed users are not encrypted since they are managed server-side. 374 encryptable_user_types.Remove(MANAGED_USERS); 375 // Proxy types have no sync representation and are therefore not encrypted. 376 // Note however that proxy types map to one or more protocol types, which 377 // may or may not be encrypted themselves. 378 encryptable_user_types.RemoveAll(ProxyTypes()); 379 return encryptable_user_types; 380 } 381 382 ModelTypeSet PriorityUserTypes() { 383 return ModelTypeSet(PRIORITY_PREFERENCES); 384 } 385 386 ModelTypeSet ControlTypes() { 387 ModelTypeSet set; 388 // TODO(sync): We should be able to build the actual enumset's internal 389 // bitset value here at compile time, rather than performing an iteration 390 // every time. 391 for (int i = FIRST_CONTROL_MODEL_TYPE; i <= LAST_CONTROL_MODEL_TYPE; ++i) { 392 set.Put(ModelTypeFromInt(i)); 393 } 394 395 return set; 396 } 397 398 ModelTypeSet ProxyTypes() { 399 ModelTypeSet set; 400 set.Put(PROXY_TABS); 401 return set; 402 } 403 404 bool IsControlType(ModelType model_type) { 405 return ControlTypes().Has(model_type); 406 } 407 408 ModelTypeSet CoreTypes() { 409 syncer::ModelTypeSet result; 410 result.PutAll(PriorityCoreTypes()); 411 412 // The following are low priority core types. 413 result.Put(SYNCED_NOTIFICATIONS); 414 415 return result; 416 } 417 418 ModelTypeSet PriorityCoreTypes() { 419 syncer::ModelTypeSet result; 420 result.PutAll(ControlTypes()); 421 422 // The following are non-control core types. 423 result.Put(MANAGED_USERS); 424 425 return result; 426 } 427 428 const char* ModelTypeToString(ModelType model_type) { 429 // This is used in serialization routines as well as for displaying debug 430 // information. Do not attempt to change these string values unless you know 431 // what you're doing. 432 switch (model_type) { 433 case TOP_LEVEL_FOLDER: 434 return "Top Level Folder"; 435 case UNSPECIFIED: 436 return "Unspecified"; 437 case BOOKMARKS: 438 return "Bookmarks"; 439 case PREFERENCES: 440 return "Preferences"; 441 case PASSWORDS: 442 return "Passwords"; 443 case AUTOFILL: 444 return "Autofill"; 445 case THEMES: 446 return "Themes"; 447 case TYPED_URLS: 448 return "Typed URLs"; 449 case EXTENSIONS: 450 return "Extensions"; 451 case NIGORI: 452 return "Encryption keys"; 453 case SEARCH_ENGINES: 454 return "Search Engines"; 455 case SESSIONS: 456 return "Sessions"; 457 case APPS: 458 return "Apps"; 459 case AUTOFILL_PROFILE: 460 return "Autofill Profiles"; 461 case APP_SETTINGS: 462 return "App settings"; 463 case EXTENSION_SETTINGS: 464 return "Extension settings"; 465 case APP_NOTIFICATIONS: 466 return "App Notifications"; 467 case HISTORY_DELETE_DIRECTIVES: 468 return "History Delete Directives"; 469 case SYNCED_NOTIFICATIONS: 470 return "Synced Notifications"; 471 case DEVICE_INFO: 472 return "Device Info"; 473 case EXPERIMENTS: 474 return "Experiments"; 475 case PRIORITY_PREFERENCES: 476 return "Priority Preferences"; 477 case DICTIONARY: 478 return "Dictionary"; 479 case FAVICON_IMAGES: 480 return "Favicon Images"; 481 case FAVICON_TRACKING: 482 return "Favicon Tracking"; 483 case MANAGED_USER_SETTINGS: 484 return "Managed User Settings"; 485 case MANAGED_USERS: 486 return "Managed Users"; 487 case PROXY_TABS: 488 return "Tabs"; 489 default: 490 break; 491 } 492 NOTREACHED() << "No known extension for model type."; 493 return "INVALID"; 494 } 495 496 // The normal rules about histograms apply here. Always append to the bottom of 497 // the list, and be careful to not reuse integer values that have already been 498 // assigned. Don't forget to update histograms.xml when you make changes to 499 // this list. 500 int ModelTypeToHistogramInt(ModelType model_type) { 501 switch (model_type) { 502 case UNSPECIFIED: 503 return 0; 504 case TOP_LEVEL_FOLDER: 505 return 1; 506 case BOOKMARKS: 507 return 2; 508 case PREFERENCES: 509 return 3; 510 case PASSWORDS: 511 return 4; 512 case AUTOFILL_PROFILE: 513 return 5; 514 case AUTOFILL: 515 return 6; 516 case THEMES: 517 return 7; 518 case TYPED_URLS: 519 return 8; 520 case EXTENSIONS: 521 return 9; 522 case SEARCH_ENGINES: 523 return 10; 524 case SESSIONS: 525 return 11; 526 case APPS: 527 return 12; 528 case APP_SETTINGS: 529 return 13; 530 case EXTENSION_SETTINGS: 531 return 14; 532 case APP_NOTIFICATIONS: 533 return 15; 534 case HISTORY_DELETE_DIRECTIVES: 535 return 16; 536 case NIGORI: 537 return 17; 538 case DEVICE_INFO: 539 return 18; 540 case EXPERIMENTS: 541 return 19; 542 case SYNCED_NOTIFICATIONS: 543 return 20; 544 case PRIORITY_PREFERENCES: 545 return 21; 546 case DICTIONARY: 547 return 22; 548 case FAVICON_IMAGES: 549 return 23; 550 case FAVICON_TRACKING: 551 return 24; 552 case PROXY_TABS: 553 return 25; 554 case MANAGED_USER_SETTINGS: 555 return 26; 556 case MANAGED_USERS: 557 return 27; 558 // Silence a compiler warning. 559 case MODEL_TYPE_COUNT: 560 return 0; 561 } 562 return 0; 563 } 564 565 base::StringValue* ModelTypeToValue(ModelType model_type) { 566 if (model_type >= FIRST_REAL_MODEL_TYPE) { 567 return new base::StringValue(ModelTypeToString(model_type)); 568 } else if (model_type == TOP_LEVEL_FOLDER) { 569 return new base::StringValue("Top-level folder"); 570 } else if (model_type == UNSPECIFIED) { 571 return new base::StringValue("Unspecified"); 572 } 573 NOTREACHED(); 574 return new base::StringValue(std::string()); 575 } 576 577 ModelType ModelTypeFromValue(const base::Value& value) { 578 if (value.IsType(base::Value::TYPE_STRING)) { 579 std::string result; 580 CHECK(value.GetAsString(&result)); 581 return ModelTypeFromString(result); 582 } else if (value.IsType(base::Value::TYPE_INTEGER)) { 583 int result; 584 CHECK(value.GetAsInteger(&result)); 585 return ModelTypeFromInt(result); 586 } else { 587 NOTREACHED() << "Unsupported value type: " << value.GetType(); 588 return UNSPECIFIED; 589 } 590 } 591 592 ModelType ModelTypeFromString(const std::string& model_type_string) { 593 if (model_type_string == "Bookmarks") 594 return BOOKMARKS; 595 else if (model_type_string == "Preferences") 596 return PREFERENCES; 597 else if (model_type_string == "Passwords") 598 return PASSWORDS; 599 else if (model_type_string == "Autofill") 600 return AUTOFILL; 601 else if (model_type_string == "Autofill Profiles") 602 return AUTOFILL_PROFILE; 603 else if (model_type_string == "Themes") 604 return THEMES; 605 else if (model_type_string == "Typed URLs") 606 return TYPED_URLS; 607 else if (model_type_string == "Extensions") 608 return EXTENSIONS; 609 else if (model_type_string == "Encryption keys") 610 return NIGORI; 611 else if (model_type_string == "Search Engines") 612 return SEARCH_ENGINES; 613 else if (model_type_string == "Sessions") 614 return SESSIONS; 615 else if (model_type_string == "Apps") 616 return APPS; 617 else if (model_type_string == "App settings") 618 return APP_SETTINGS; 619 else if (model_type_string == "Extension settings") 620 return EXTENSION_SETTINGS; 621 else if (model_type_string == "App Notifications") 622 return APP_NOTIFICATIONS; 623 else if (model_type_string == "History Delete Directives") 624 return HISTORY_DELETE_DIRECTIVES; 625 else if (model_type_string == "Synced Notifications") 626 return SYNCED_NOTIFICATIONS; 627 else if (model_type_string == "Device Info") 628 return DEVICE_INFO; 629 else if (model_type_string == "Experiments") 630 return EXPERIMENTS; 631 else if (model_type_string == "Priority Preferences") 632 return PRIORITY_PREFERENCES; 633 else if (model_type_string == "Dictionary") 634 return DICTIONARY; 635 else if (model_type_string == "Favicon Images") 636 return FAVICON_IMAGES; 637 else if (model_type_string == "Favicon Tracking") 638 return FAVICON_TRACKING; 639 else if (model_type_string == "Managed User Settings") 640 return MANAGED_USER_SETTINGS; 641 else if (model_type_string == "Managed Users") 642 return MANAGED_USERS; 643 else if (model_type_string == "Tabs") 644 return PROXY_TABS; 645 else 646 NOTREACHED() << "No known model type corresponding to " 647 << model_type_string << "."; 648 return UNSPECIFIED; 649 } 650 651 std::string ModelTypeSetToString(ModelTypeSet model_types) { 652 std::string result; 653 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { 654 if (!result.empty()) { 655 result += ", "; 656 } 657 result += ModelTypeToString(it.Get()); 658 } 659 return result; 660 } 661 662 base::ListValue* ModelTypeSetToValue(ModelTypeSet model_types) { 663 base::ListValue* value = new base::ListValue(); 664 for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { 665 value->Append(new base::StringValue(ModelTypeToString(it.Get()))); 666 } 667 return value; 668 } 669 670 ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value) { 671 ModelTypeSet result; 672 for (base::ListValue::const_iterator i = value.begin(); 673 i != value.end(); ++i) { 674 result.Put(ModelTypeFromValue(**i)); 675 } 676 return result; 677 } 678 679 // TODO(zea): remove all hardcoded tags in model associators and have them use 680 // this instead. 681 // NOTE: Proxy types should return empty strings (so that we don't NOTREACHED 682 // in tests when we verify they have no root node). 683 std::string ModelTypeToRootTag(ModelType type) { 684 switch (type) { 685 case BOOKMARKS: 686 return "google_chrome_bookmarks"; 687 case PREFERENCES: 688 return "google_chrome_preferences"; 689 case PASSWORDS: 690 return "google_chrome_passwords"; 691 case AUTOFILL: 692 return "google_chrome_autofill"; 693 case THEMES: 694 return "google_chrome_themes"; 695 case TYPED_URLS: 696 return "google_chrome_typed_urls"; 697 case EXTENSIONS: 698 return "google_chrome_extensions"; 699 case NIGORI: 700 return "google_chrome_nigori"; 701 case SEARCH_ENGINES: 702 return "google_chrome_search_engines"; 703 case SESSIONS: 704 return "google_chrome_sessions"; 705 case APPS: 706 return "google_chrome_apps"; 707 case AUTOFILL_PROFILE: 708 return "google_chrome_autofill_profiles"; 709 case APP_SETTINGS: 710 return "google_chrome_app_settings"; 711 case EXTENSION_SETTINGS: 712 return "google_chrome_extension_settings"; 713 case APP_NOTIFICATIONS: 714 return "google_chrome_app_notifications"; 715 case HISTORY_DELETE_DIRECTIVES: 716 return "google_chrome_history_delete_directives"; 717 case SYNCED_NOTIFICATIONS: 718 return "google_chrome_synced_notifications"; 719 case DEVICE_INFO: 720 return "google_chrome_device_info"; 721 case EXPERIMENTS: 722 return "google_chrome_experiments"; 723 case PRIORITY_PREFERENCES: 724 return "google_chrome_priority_preferences"; 725 case DICTIONARY: 726 return "google_chrome_dictionary"; 727 case FAVICON_IMAGES: 728 return "google_chrome_favicon_images"; 729 case FAVICON_TRACKING: 730 return "google_chrome_favicon_tracking"; 731 case MANAGED_USER_SETTINGS: 732 return "google_chrome_managed_user_settings"; 733 case MANAGED_USERS: 734 return "google_chrome_managed_users"; 735 case PROXY_TABS: 736 return std::string(); 737 default: 738 break; 739 } 740 NOTREACHED() << "No known extension for model type."; 741 return "INVALID"; 742 } 743 744 // TODO(akalin): Figure out a better way to do these mappings. 745 // Note: Do not include proxy types in this list. They should never receive 746 // or trigger notifications. 747 namespace { 748 const char kBookmarkNotificationType[] = "BOOKMARK"; 749 const char kPreferenceNotificationType[] = "PREFERENCE"; 750 const char kPasswordNotificationType[] = "PASSWORD"; 751 const char kAutofillNotificationType[] = "AUTOFILL"; 752 const char kThemeNotificationType[] = "THEME"; 753 const char kTypedUrlNotificationType[] = "TYPED_URL"; 754 const char kExtensionNotificationType[] = "EXTENSION"; 755 const char kExtensionSettingNotificationType[] = "EXTENSION_SETTING"; 756 const char kNigoriNotificationType[] = "NIGORI"; 757 const char kAppSettingNotificationType[] = "APP_SETTING"; 758 const char kAppNotificationType[] = "APP"; 759 const char kSearchEngineNotificationType[] = "SEARCH_ENGINE"; 760 const char kSessionNotificationType[] = "SESSION"; 761 const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE"; 762 const char kAppNotificationNotificationType[] = "APP_NOTIFICATION"; 763 const char kHistoryDeleteDirectiveNotificationType[] = 764 "HISTORY_DELETE_DIRECTIVE"; 765 const char kSyncedNotificationType[] = "SYNCED_NOTIFICATION"; 766 const char kDeviceInfoNotificationType[] = "DEVICE_INFO"; 767 const char kExperimentsNotificationType[] = "EXPERIMENTS"; 768 const char kPriorityPreferenceNotificationType[] = "PRIORITY_PREFERENCE"; 769 const char kDictionaryNotificationType[] = "DICTIONARY"; 770 const char kFaviconImageNotificationType[] = "FAVICON_IMAGE"; 771 const char kFaviconTrackingNotificationType[] = "FAVICON_TRACKING"; 772 const char kManagedUserSettingNotificationType[] = "MANAGED_USER_SETTING"; 773 const char kManagedUserNotificationType[] = "MANAGED_USER"; 774 } // namespace 775 776 bool RealModelTypeToNotificationType(ModelType model_type, 777 std::string* notification_type) { 778 switch (model_type) { 779 case BOOKMARKS: 780 *notification_type = kBookmarkNotificationType; 781 return true; 782 case PREFERENCES: 783 *notification_type = kPreferenceNotificationType; 784 return true; 785 case PASSWORDS: 786 *notification_type = kPasswordNotificationType; 787 return true; 788 case AUTOFILL: 789 *notification_type = kAutofillNotificationType; 790 return true; 791 case THEMES: 792 *notification_type = kThemeNotificationType; 793 return true; 794 case TYPED_URLS: 795 *notification_type = kTypedUrlNotificationType; 796 return true; 797 case EXTENSIONS: 798 *notification_type = kExtensionNotificationType; 799 return true; 800 case NIGORI: 801 *notification_type = kNigoriNotificationType; 802 return true; 803 case APP_SETTINGS: 804 *notification_type = kAppSettingNotificationType; 805 return true; 806 case APPS: 807 *notification_type = kAppNotificationType; 808 return true; 809 case SEARCH_ENGINES: 810 *notification_type = kSearchEngineNotificationType; 811 return true; 812 case SESSIONS: 813 *notification_type = kSessionNotificationType; 814 return true; 815 case AUTOFILL_PROFILE: 816 *notification_type = kAutofillProfileNotificationType; 817 return true; 818 case EXTENSION_SETTINGS: 819 *notification_type = kExtensionSettingNotificationType; 820 return true; 821 case APP_NOTIFICATIONS: 822 *notification_type = kAppNotificationNotificationType; 823 return true; 824 case HISTORY_DELETE_DIRECTIVES: 825 *notification_type = kHistoryDeleteDirectiveNotificationType; 826 return true; 827 case SYNCED_NOTIFICATIONS: 828 *notification_type = kSyncedNotificationType; 829 return true; 830 case DEVICE_INFO: 831 *notification_type = kDeviceInfoNotificationType; 832 return true; 833 case EXPERIMENTS: 834 *notification_type = kExperimentsNotificationType; 835 return true; 836 case PRIORITY_PREFERENCES: 837 *notification_type = kPriorityPreferenceNotificationType; 838 return true; 839 case DICTIONARY: 840 *notification_type = kDictionaryNotificationType; 841 return true; 842 case FAVICON_IMAGES: 843 *notification_type = kFaviconImageNotificationType; 844 return true; 845 case FAVICON_TRACKING: 846 *notification_type = kFaviconTrackingNotificationType; 847 return true; 848 case MANAGED_USER_SETTINGS: 849 *notification_type = kManagedUserSettingNotificationType; 850 return true; 851 case MANAGED_USERS: 852 *notification_type = kManagedUserNotificationType; 853 return true; 854 default: 855 break; 856 } 857 notification_type->clear(); 858 return false; 859 } 860 861 bool NotificationTypeToRealModelType(const std::string& notification_type, 862 ModelType* model_type) { 863 if (notification_type == kBookmarkNotificationType) { 864 *model_type = BOOKMARKS; 865 return true; 866 } else if (notification_type == kPreferenceNotificationType) { 867 *model_type = PREFERENCES; 868 return true; 869 } else if (notification_type == kPasswordNotificationType) { 870 *model_type = PASSWORDS; 871 return true; 872 } else if (notification_type == kAutofillNotificationType) { 873 *model_type = AUTOFILL; 874 return true; 875 } else if (notification_type == kThemeNotificationType) { 876 *model_type = THEMES; 877 return true; 878 } else if (notification_type == kTypedUrlNotificationType) { 879 *model_type = TYPED_URLS; 880 return true; 881 } else if (notification_type == kExtensionNotificationType) { 882 *model_type = EXTENSIONS; 883 return true; 884 } else if (notification_type == kNigoriNotificationType) { 885 *model_type = NIGORI; 886 return true; 887 } else if (notification_type == kAppNotificationType) { 888 *model_type = APPS; 889 return true; 890 } else if (notification_type == kSearchEngineNotificationType) { 891 *model_type = SEARCH_ENGINES; 892 return true; 893 } else if (notification_type == kSessionNotificationType) { 894 *model_type = SESSIONS; 895 return true; 896 } else if (notification_type == kAutofillProfileNotificationType) { 897 *model_type = AUTOFILL_PROFILE; 898 return true; 899 } else if (notification_type == kAppSettingNotificationType) { 900 *model_type = APP_SETTINGS; 901 return true; 902 } else if (notification_type == kExtensionSettingNotificationType) { 903 *model_type = EXTENSION_SETTINGS; 904 return true; 905 } else if (notification_type == kAppNotificationNotificationType) { 906 *model_type = APP_NOTIFICATIONS; 907 return true; 908 } else if (notification_type == kHistoryDeleteDirectiveNotificationType) { 909 *model_type = HISTORY_DELETE_DIRECTIVES; 910 return true; 911 } else if (notification_type == kSyncedNotificationType) { 912 *model_type = SYNCED_NOTIFICATIONS; 913 return true; 914 } else if (notification_type == kDeviceInfoNotificationType) { 915 *model_type = DEVICE_INFO; 916 return true; 917 } else if (notification_type == kExperimentsNotificationType) { 918 *model_type = EXPERIMENTS; 919 return true; 920 } else if (notification_type == kPriorityPreferenceNotificationType) { 921 *model_type = PRIORITY_PREFERENCES; 922 return true; 923 } else if (notification_type == kDictionaryNotificationType) { 924 *model_type = DICTIONARY; 925 return true; 926 } else if (notification_type == kFaviconImageNotificationType) { 927 *model_type = FAVICON_IMAGES; 928 return true; 929 } else if (notification_type == kFaviconTrackingNotificationType) { 930 *model_type = FAVICON_TRACKING; 931 return true; 932 } else if (notification_type == kManagedUserSettingNotificationType) { 933 *model_type = MANAGED_USER_SETTINGS; 934 return true; 935 } else if (notification_type == kManagedUserNotificationType) { 936 *model_type = MANAGED_USERS; 937 return true; 938 } 939 *model_type = UNSPECIFIED; 940 return false; 941 } 942 943 bool IsRealDataType(ModelType model_type) { 944 return model_type >= FIRST_REAL_MODEL_TYPE && model_type < MODEL_TYPE_COUNT; 945 } 946 947 bool IsActOnceDataType(ModelType model_type) { 948 return model_type == HISTORY_DELETE_DIRECTIVES; 949 } 950 951 } // namespace syncer 952