Home | History | Annotate | Download | only in protocol
      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 // Keep this file in sync with the .proto files in this directory.
      6 
      7 #include "sync/protocol/proto_value_conversions.h"
      8 
      9 #include <string>
     10 
     11 #include "base/base64.h"
     12 #include "base/basictypes.h"
     13 #include "base/logging.h"
     14 #include "base/strings/string_number_conversions.h"
     15 #include "base/values.h"
     16 #include "sync/internal_api/public/base/unique_position.h"
     17 #include "sync/protocol/app_list_specifics.pb.h"
     18 #include "sync/protocol/app_notification_specifics.pb.h"
     19 #include "sync/protocol/app_setting_specifics.pb.h"
     20 #include "sync/protocol/app_specifics.pb.h"
     21 #include "sync/protocol/autofill_specifics.pb.h"
     22 #include "sync/protocol/bookmark_specifics.pb.h"
     23 #include "sync/protocol/dictionary_specifics.pb.h"
     24 #include "sync/protocol/encryption.pb.h"
     25 #include "sync/protocol/experiments_specifics.pb.h"
     26 #include "sync/protocol/extension_setting_specifics.pb.h"
     27 #include "sync/protocol/extension_specifics.pb.h"
     28 #include "sync/protocol/favicon_image_specifics.pb.h"
     29 #include "sync/protocol/favicon_tracking_specifics.pb.h"
     30 #include "sync/protocol/history_delete_directive_specifics.pb.h"
     31 #include "sync/protocol/nigori_specifics.pb.h"
     32 #include "sync/protocol/password_specifics.pb.h"
     33 #include "sync/protocol/preference_specifics.pb.h"
     34 #include "sync/protocol/priority_preference_specifics.pb.h"
     35 #include "sync/protocol/proto_enum_conversions.h"
     36 #include "sync/protocol/search_engine_specifics.pb.h"
     37 #include "sync/protocol/session_specifics.pb.h"
     38 #include "sync/protocol/sync.pb.h"
     39 #include "sync/protocol/synced_notification_specifics.pb.h"
     40 #include "sync/protocol/theme_specifics.pb.h"
     41 #include "sync/protocol/typed_url_specifics.pb.h"
     42 #include "sync/protocol/unique_position.pb.h"
     43 
     44 namespace syncer {
     45 
     46 namespace {
     47 
     48 // Basic Type -> Value functions.
     49 
     50 base::StringValue* MakeInt64Value(int64 x) {
     51   return new base::StringValue(base::Int64ToString(x));
     52 }
     53 
     54 // TODO(akalin): Perhaps make JSONWriter support BinaryValue and use
     55 // that instead of a StringValue.
     56 base::StringValue* MakeBytesValue(const std::string& bytes) {
     57   std::string bytes_base64;
     58   base::Base64Encode(bytes, &bytes_base64);
     59   return new base::StringValue(bytes_base64);
     60 }
     61 
     62 base::StringValue* MakeStringValue(const std::string& str) {
     63   return new base::StringValue(str);
     64 }
     65 
     66 // T is the enum type.
     67 template <class T>
     68 base::StringValue* MakeEnumValue(T t, const char* (*converter_fn)(T)) {
     69   return new base::StringValue(converter_fn(t));
     70 }
     71 
     72 // T is the field type, F is either RepeatedField or RepeatedPtrField,
     73 // and V is a subclass of Value.
     74 template <class T, class F, class V>
     75 base::ListValue* MakeRepeatedValue(const F& fields, V* (*converter_fn)(T)) {
     76   base::ListValue* list = new base::ListValue();
     77   for (typename F::const_iterator it = fields.begin(); it != fields.end();
     78        ++it) {
     79     list->Append(converter_fn(*it));
     80   }
     81   return list;
     82 }
     83 
     84 }  // namespace
     85 
     86 // Helper macros to reduce the amount of boilerplate.
     87 
     88 #define SET(field, fn) \
     89   if (proto.has_##field()) { \
     90     value->Set(#field, fn(proto.field())); \
     91   }
     92 #define SET_REP(field, fn) \
     93   value->Set(#field, MakeRepeatedValue(proto.field(), fn))
     94 #define SET_ENUM(field, fn) \
     95   value->Set(#field, MakeEnumValue(proto.field(), fn))
     96 
     97 #define SET_BOOL(field) SET(field, new base::FundamentalValue)
     98 #define SET_BYTES(field) SET(field, MakeBytesValue)
     99 #define SET_INT32(field) SET(field, MakeInt64Value)
    100 #define SET_INT32_REP(field) SET_REP(field, MakeInt64Value)
    101 #define SET_INT64(field) SET(field, MakeInt64Value)
    102 #define SET_INT64_REP(field) SET_REP(field, MakeInt64Value)
    103 #define SET_STR(field) SET(field, new base::StringValue)
    104 #define SET_STR_REP(field) \
    105   value->Set(#field, \
    106              MakeRepeatedValue<const std::string&, \
    107                                google::protobuf::RepeatedPtrField< \
    108                                    std::string >, \
    109                                base::StringValue>(proto.field(), \
    110                                             MakeStringValue))
    111 #define SET_EXPERIMENT_ENABLED_FIELD(field)          \
    112   do {                                               \
    113     if (proto.has_##field() &&                       \
    114         proto.field().has_enabled()) {               \
    115       value->Set(#field,                             \
    116                  new base::FundamentalValue(         \
    117                      proto.field().enabled()));      \
    118     }                                                \
    119   } while (0)
    120 
    121 #define SET_FIELD(field, fn)                         \
    122   do {                                               \
    123     if (specifics.has_##field()) {                   \
    124       value->Set(#field, fn(specifics.field()));     \
    125     }                                                \
    126   } while (0)
    127 
    128 // If you add another macro, don't forget to add an #undef at the end
    129 // of this file, too.
    130 
    131 base::DictionaryValue* EncryptedDataToValue(
    132     const sync_pb::EncryptedData& proto) {
    133   base::DictionaryValue* value = new base::DictionaryValue();
    134   SET_STR(key_name);
    135   // TODO(akalin): Shouldn't blob be of type bytes instead of string?
    136   SET_BYTES(blob);
    137   return value;
    138 }
    139 
    140 base::DictionaryValue* AppSettingsToValue(
    141     const sync_pb::AppNotificationSettings& proto) {
    142   base::DictionaryValue* value = new base::DictionaryValue();
    143   SET_BOOL(initial_setup_done);
    144   SET_BOOL(disabled);
    145   SET_STR(oauth_client_id);
    146   return value;
    147 }
    148 
    149 base::DictionaryValue* SessionHeaderToValue(
    150     const sync_pb::SessionHeader& proto) {
    151   base::DictionaryValue* value = new base::DictionaryValue();
    152   SET_REP(window, SessionWindowToValue);
    153   SET_STR(client_name);
    154   SET_ENUM(device_type, GetDeviceTypeString);
    155   return value;
    156 }
    157 
    158 base::DictionaryValue* SessionTabToValue(const sync_pb::SessionTab& proto) {
    159   base::DictionaryValue* value = new base::DictionaryValue();
    160   SET_INT32(tab_id);
    161   SET_INT32(window_id);
    162   SET_INT32(tab_visual_index);
    163   SET_INT32(current_navigation_index);
    164   SET_BOOL(pinned);
    165   SET_STR(extension_app_id);
    166   SET_REP(navigation, TabNavigationToValue);
    167   SET_BYTES(favicon);
    168   SET_ENUM(favicon_type, GetFaviconTypeString);
    169   SET_STR(favicon_source);
    170   return value;
    171 }
    172 
    173 base::DictionaryValue* SessionWindowToValue(
    174     const sync_pb::SessionWindow& proto) {
    175   base::DictionaryValue* value = new base::DictionaryValue();
    176   SET_INT32(window_id);
    177   SET_INT32(selected_tab_index);
    178   SET_INT32_REP(tab);
    179   SET_ENUM(browser_type, GetBrowserTypeString);
    180   return value;
    181 }
    182 
    183 base::DictionaryValue* TabNavigationToValue(
    184     const sync_pb::TabNavigation& proto) {
    185   base::DictionaryValue* value = new base::DictionaryValue();
    186   SET_STR(virtual_url);
    187   SET_STR(referrer);
    188   SET_STR(title);
    189   SET_STR(state);
    190   SET_ENUM(page_transition, GetPageTransitionString);
    191   SET_ENUM(redirect_type, GetPageTransitionRedirectTypeString);
    192   SET_INT32(unique_id);
    193   SET_INT64(timestamp_msec);
    194   SET_BOOL(navigation_forward_back);
    195   SET_BOOL(navigation_from_address_bar);
    196   SET_BOOL(navigation_home_page);
    197   SET_BOOL(navigation_chain_start);
    198   SET_BOOL(navigation_chain_end);
    199   SET_INT64(global_id);
    200   SET_STR(search_terms);
    201   SET_STR(favicon_url);
    202   SET_ENUM(blocked_state, GetBlockedStateString);
    203   SET_STR_REP(content_pack_categories);
    204   SET_INT32(http_status_code);
    205   return value;
    206 }
    207 
    208 base::DictionaryValue* PasswordSpecificsDataToValue(
    209     const sync_pb::PasswordSpecificsData& proto) {
    210   base::DictionaryValue* value = new base::DictionaryValue();
    211   SET_INT32(scheme);
    212   SET_STR(signon_realm);
    213   SET_STR(origin);
    214   SET_STR(action);
    215   SET_STR(username_element);
    216   SET_STR(username_value);
    217   SET_STR(password_element);
    218   value->SetString("password_value", "<redacted>");
    219   SET_BOOL(ssl_valid);
    220   SET_BOOL(preferred);
    221   SET_INT64(date_created);
    222   SET_BOOL(blacklisted);
    223   return value;
    224 }
    225 
    226 base::DictionaryValue* GlobalIdDirectiveToValue(
    227     const sync_pb::GlobalIdDirective& proto) {
    228   base::DictionaryValue* value = new base::DictionaryValue();
    229   SET_INT64_REP(global_id);
    230   SET_INT64(start_time_usec);
    231   SET_INT64(end_time_usec);
    232   return value;
    233 }
    234 
    235 base::DictionaryValue* TimeRangeDirectiveToValue(
    236     const sync_pb::TimeRangeDirective& proto) {
    237   base::DictionaryValue* value = new base::DictionaryValue();
    238   SET_INT64(start_time_usec);
    239   SET_INT64(end_time_usec);
    240   return value;
    241 }
    242 
    243 base::DictionaryValue* SyncedNotificationImageToValue(
    244     const sync_pb::SyncedNotificationImage& proto) {
    245   base::DictionaryValue* value = new base::DictionaryValue();
    246   SET_STR(url);
    247   SET_STR(alt_text);
    248   SET_INT32(preferred_width);
    249   SET_INT32(preferred_height);
    250   return value;
    251 }
    252 
    253 base::DictionaryValue* SyncedNotificationProfileImageToValue(
    254     const sync_pb::SyncedNotificationProfileImage& proto) {
    255   base::DictionaryValue* value = new base::DictionaryValue();
    256   SET_STR(image_url);
    257   SET_STR(oid);
    258   SET_STR(display_name);
    259   return value;
    260 }
    261 
    262 base::DictionaryValue* MediaToValue(
    263     const sync_pb::Media& proto) {
    264   base::DictionaryValue* value = new base::DictionaryValue();
    265   SET(image, SyncedNotificationImageToValue);
    266   return value;
    267 }
    268 
    269 base::DictionaryValue* SyncedNotificationActionToValue(
    270     const sync_pb::SyncedNotificationAction& proto) {
    271   base::DictionaryValue* value = new base::DictionaryValue();
    272   SET_STR(text);
    273   SET(icon, SyncedNotificationImageToValue);
    274   SET_STR(url);
    275   SET_STR(request_data);
    276   SET_STR(accessibility_label);
    277   return value;
    278 }
    279 
    280 base::DictionaryValue* SyncedNotificationDestiationToValue(
    281     const sync_pb::SyncedNotificationDestination& proto) {
    282   base::DictionaryValue* value = new base::DictionaryValue();
    283   SET_STR(text);
    284   SET(icon, SyncedNotificationImageToValue);
    285   SET_STR(url);
    286   SET_STR(accessibility_label);
    287   return value;
    288 }
    289 
    290 base::DictionaryValue* TargetToValue(
    291     const sync_pb::Target& proto) {
    292   base::DictionaryValue* value = new base::DictionaryValue();
    293   SET(destination, SyncedNotificationDestiationToValue);
    294   SET(action, SyncedNotificationActionToValue);
    295   SET_STR(target_key);
    296   return value;
    297 }
    298 
    299 base::DictionaryValue* SimpleCollapsedLayoutToValue(
    300     const sync_pb::SimpleCollapsedLayout& proto) {
    301   base::DictionaryValue* value = new base::DictionaryValue();
    302   SET(app_icon, SyncedNotificationImageToValue);
    303   SET_REP(profile_image, SyncedNotificationProfileImageToValue);
    304   SET_STR(heading);
    305   SET_STR(description);
    306   SET_STR(annotation);
    307   SET_REP(media, MediaToValue);
    308   return value;
    309 }
    310 
    311 base::DictionaryValue* CollapsedInfoToValue(
    312     const sync_pb::CollapsedInfo& proto) {
    313   base::DictionaryValue* value = new base::DictionaryValue();
    314   SET(simple_collapsed_layout, SimpleCollapsedLayoutToValue);
    315   SET_INT64(creation_timestamp_usec);
    316   SET(default_destination, SyncedNotificationDestiationToValue);
    317   SET_REP(target, TargetToValue);
    318   return value;
    319 }
    320 
    321 base::DictionaryValue* SyncedNotificationToValue(
    322     const sync_pb::SyncedNotification& proto) {
    323   base::DictionaryValue* value = new base::DictionaryValue();
    324   SET_STR(type);
    325   SET_STR(external_id);
    326   // TODO(petewil) Add SyncedNotificationCreator here if we ever need it.
    327   return value;
    328 }
    329 
    330 base::DictionaryValue* RenderInfoToValue(
    331     const sync_pb::SyncedNotificationRenderInfo& proto) {
    332   base::DictionaryValue* value = new base::DictionaryValue();
    333   // TODO(petewil): Add the expanded info values once we start using them.
    334   SET(collapsed_info, CollapsedInfoToValue);
    335   return value;
    336 }
    337 
    338 base::DictionaryValue* CoalescedNotificationToValue(
    339     const sync_pb::CoalescedSyncedNotification& proto) {
    340   base::DictionaryValue* value = new base::DictionaryValue();
    341   SET_STR(key);
    342   SET_STR(app_id);
    343   SET_REP(notification, SyncedNotificationToValue);
    344   SET(render_info, RenderInfoToValue);
    345   SET_INT32(read_state);
    346   SET_INT64(creation_time_msec);
    347   SET_INT32(priority);
    348   return value;
    349 }
    350 
    351 base::DictionaryValue* AppListSpecificsToValue(
    352     const sync_pb::AppListSpecifics& proto) {
    353   base::DictionaryValue* value = new base::DictionaryValue();
    354   SET_STR(item_id);
    355   SET_ENUM(item_type, GetAppListItemTypeString);
    356   SET_STR(item_name);
    357   SET_STR(parent_id);
    358   SET_STR(page_ordinal);
    359   SET_STR(item_ordinal);
    360 
    361   return value;
    362 }
    363 
    364 base::DictionaryValue* AppNotificationToValue(
    365     const sync_pb::AppNotification& proto) {
    366   base::DictionaryValue* value = new base::DictionaryValue();
    367   SET_STR(guid);
    368   SET_STR(app_id);
    369   SET_INT64(creation_timestamp_ms);
    370   SET_STR(title);
    371   SET_STR(body_text);
    372   SET_STR(link_url);
    373   SET_STR(link_text);
    374   return value;
    375 }
    376 
    377 base::DictionaryValue* AppSettingSpecificsToValue(
    378     const sync_pb::AppSettingSpecifics& proto) {
    379   base::DictionaryValue* value = new base::DictionaryValue();
    380   SET(extension_setting, ExtensionSettingSpecificsToValue);
    381   return value;
    382 }
    383 
    384 base::DictionaryValue* AppSpecificsToValue(
    385     const sync_pb::AppSpecifics& proto) {
    386   base::DictionaryValue* value = new base::DictionaryValue();
    387   SET(extension, ExtensionSpecificsToValue);
    388   SET(notification_settings, AppSettingsToValue);
    389   SET_STR(app_launch_ordinal);
    390   SET_STR(page_ordinal);
    391 
    392   return value;
    393 }
    394 
    395 base::DictionaryValue* AutofillSpecificsToValue(
    396     const sync_pb::AutofillSpecifics& proto) {
    397   base::DictionaryValue* value = new base::DictionaryValue();
    398   SET_STR(name);
    399   SET_STR(value);
    400   SET_INT64_REP(usage_timestamp);
    401   SET(profile, AutofillProfileSpecificsToValue);
    402   return value;
    403 }
    404 
    405 base::DictionaryValue* AutofillProfileSpecificsToValue(
    406     const sync_pb::AutofillProfileSpecifics& proto) {
    407   base::DictionaryValue* value = new base::DictionaryValue();
    408   SET_STR(guid);
    409   SET_STR(origin);
    410 
    411   SET_STR_REP(name_first);
    412   SET_STR_REP(name_middle);
    413   SET_STR_REP(name_last);
    414   SET_STR_REP(email_address);
    415   SET_STR(company_name);
    416 
    417   SET_STR(address_home_line1);
    418   SET_STR(address_home_line2);
    419   SET_STR(address_home_city);
    420   SET_STR(address_home_state);
    421   SET_STR(address_home_zip);
    422   SET_STR(address_home_country);
    423 
    424   SET_STR_REP(phone_home_whole_number);
    425   return value;
    426 }
    427 
    428 base::DictionaryValue* MetaInfoToValue(
    429     const sync_pb::MetaInfo& proto) {
    430   base::DictionaryValue* value = new base::DictionaryValue();
    431   SET_STR(key);
    432   SET_STR(value);
    433   return value;
    434 }
    435 
    436 base::DictionaryValue* BookmarkSpecificsToValue(
    437     const sync_pb::BookmarkSpecifics& proto) {
    438   base::DictionaryValue* value = new base::DictionaryValue();
    439   SET_STR(url);
    440   SET_BYTES(favicon);
    441   SET_STR(title);
    442   SET_INT64(creation_time_us);
    443   SET_STR(icon_url);
    444   SET_REP(meta_info, &MetaInfoToValue);
    445   return value;
    446 }
    447 
    448 base::DictionaryValue* DeviceInfoSpecificsToValue(
    449     const sync_pb::DeviceInfoSpecifics& proto) {
    450   base::DictionaryValue* value = new base::DictionaryValue();
    451   SET_STR(cache_guid);
    452   SET_STR(client_name);
    453   SET_ENUM(device_type, GetDeviceTypeString);
    454   SET_STR(sync_user_agent);
    455   SET_STR(chrome_version);
    456   return value;
    457 }
    458 
    459 base::DictionaryValue* DictionarySpecificsToValue(
    460     const sync_pb::DictionarySpecifics& proto) {
    461   base::DictionaryValue* value = new base::DictionaryValue();
    462   SET_STR(word);
    463   return value;
    464 }
    465 
    466 namespace {
    467 
    468 base::DictionaryValue* FaviconSyncFlagsToValue(
    469     const sync_pb::FaviconSyncFlags& proto) {
    470   base::DictionaryValue* value = new base::DictionaryValue();
    471   SET_BOOL(enabled);
    472   SET_INT32(favicon_sync_limit);
    473   return value;
    474 }
    475 
    476 }  // namespace
    477 
    478 base::DictionaryValue* ExperimentsSpecificsToValue(
    479     const sync_pb::ExperimentsSpecifics& proto) {
    480   base::DictionaryValue* value = new base::DictionaryValue();
    481   SET_EXPERIMENT_ENABLED_FIELD(keystore_encryption);
    482   SET_EXPERIMENT_ENABLED_FIELD(history_delete_directives);
    483   SET_EXPERIMENT_ENABLED_FIELD(autofill_culling);
    484   SET_EXPERIMENT_ENABLED_FIELD(pre_commit_update_avoidance);
    485   if (proto.has_favicon_sync())
    486     SET(favicon_sync, FaviconSyncFlagsToValue);
    487   return value;
    488 }
    489 
    490 base::DictionaryValue* ExtensionSettingSpecificsToValue(
    491     const sync_pb::ExtensionSettingSpecifics& proto) {
    492   base::DictionaryValue* value = new base::DictionaryValue();
    493   SET_STR(extension_id);
    494   SET_STR(key);
    495   SET_STR(value);
    496   return value;
    497 }
    498 
    499 base::DictionaryValue* ExtensionSpecificsToValue(
    500     const sync_pb::ExtensionSpecifics& proto) {
    501   base::DictionaryValue* value = new base::DictionaryValue();
    502   SET_STR(id);
    503   SET_STR(version);
    504   SET_STR(update_url);
    505   SET_BOOL(enabled);
    506   SET_BOOL(incognito_enabled);
    507   SET_STR(name);
    508   return value;
    509 }
    510 
    511 namespace {
    512 base::DictionaryValue* FaviconDataToValue(
    513     const sync_pb::FaviconData& proto) {
    514   base::DictionaryValue* value = new base::DictionaryValue();
    515   SET_BYTES(favicon);
    516   SET_INT32(width);
    517   SET_INT32(height);
    518   return value;
    519 }
    520 }  // namespace
    521 
    522 base::DictionaryValue* FaviconImageSpecificsToValue(
    523     const sync_pb::FaviconImageSpecifics& proto) {
    524   base::DictionaryValue* value = new base::DictionaryValue();
    525   SET_STR(favicon_url);
    526   SET(favicon_web, FaviconDataToValue);
    527   SET(favicon_web_32, FaviconDataToValue);
    528   SET(favicon_touch_64, FaviconDataToValue);
    529   SET(favicon_touch_precomposed_64, FaviconDataToValue);
    530   return value;
    531 }
    532 
    533 base::DictionaryValue* FaviconTrackingSpecificsToValue(
    534     const sync_pb::FaviconTrackingSpecifics& proto) {
    535   base::DictionaryValue* value = new base::DictionaryValue();
    536   SET_STR(favicon_url);
    537   SET_INT64(last_visit_time_ms)
    538   SET_BOOL(is_bookmarked);
    539   return value;
    540 }
    541 
    542 base::DictionaryValue* HistoryDeleteDirectiveSpecificsToValue(
    543     const sync_pb::HistoryDeleteDirectiveSpecifics& proto) {
    544   base::DictionaryValue* value = new base::DictionaryValue();
    545   SET(global_id_directive, GlobalIdDirectiveToValue);
    546   SET(time_range_directive, TimeRangeDirectiveToValue);
    547   return value;
    548 }
    549 
    550 base::DictionaryValue* ManagedUserSettingSpecificsToValue(
    551     const sync_pb::ManagedUserSettingSpecifics& proto) {
    552   base::DictionaryValue* value = new base::DictionaryValue();
    553   SET_STR(name);
    554   SET_STR(value);
    555   return value;
    556 }
    557 
    558 base::DictionaryValue* ManagedUserSpecificsToValue(
    559     const sync_pb::ManagedUserSpecifics& proto) {
    560   base::DictionaryValue* value = new base::DictionaryValue();
    561   SET_STR(id);
    562   SET_STR(name);
    563   SET_BOOL(acknowledged);
    564   SET_STR(master_key);
    565   SET_STR(chrome_avatar);
    566   SET_STR(chromeos_avatar);
    567   return value;
    568 }
    569 
    570 base::DictionaryValue* NigoriSpecificsToValue(
    571     const sync_pb::NigoriSpecifics& proto) {
    572   base::DictionaryValue* value = new base::DictionaryValue();
    573   SET(encryption_keybag, EncryptedDataToValue);
    574   SET_BOOL(keybag_is_frozen);
    575   SET_BOOL(encrypt_bookmarks);
    576   SET_BOOL(encrypt_preferences);
    577   SET_BOOL(encrypt_autofill_profile);
    578   SET_BOOL(encrypt_autofill);
    579   SET_BOOL(encrypt_themes);
    580   SET_BOOL(encrypt_typed_urls);
    581   SET_BOOL(encrypt_extension_settings);
    582   SET_BOOL(encrypt_extensions);
    583   SET_BOOL(encrypt_sessions);
    584   SET_BOOL(encrypt_app_settings);
    585   SET_BOOL(encrypt_apps);
    586   SET_BOOL(encrypt_search_engines);
    587   SET_BOOL(encrypt_dictionary);
    588   SET_BOOL(encrypt_articles);
    589   SET_BOOL(encrypt_app_list);
    590   SET_BOOL(encrypt_everything);
    591   SET_BOOL(sync_tab_favicons);
    592   SET_ENUM(passphrase_type, PassphraseTypeString);
    593   SET(keystore_decryptor_token, EncryptedDataToValue);
    594   SET_INT64(keystore_migration_time);
    595   SET_INT64(custom_passphrase_time);
    596   return value;
    597 }
    598 
    599 base::DictionaryValue* ArticlePageToValue(
    600     const sync_pb::ArticlePage& proto) {
    601   base::DictionaryValue* value = new base::DictionaryValue();
    602   SET_STR(url);
    603   return value;
    604 }
    605 
    606 base::DictionaryValue* ArticleSpecificsToValue(
    607     const sync_pb::ArticleSpecifics& proto) {
    608   base::DictionaryValue* value = new base::DictionaryValue();
    609   SET_STR(entry_id);
    610   SET_STR(title);
    611   SET_REP(pages, ArticlePageToValue);
    612   return value;
    613 }
    614 
    615 base::DictionaryValue* PasswordSpecificsToValue(
    616     const sync_pb::PasswordSpecifics& proto) {
    617   base::DictionaryValue* value = new base::DictionaryValue();
    618   SET(encrypted, EncryptedDataToValue);
    619   return value;
    620 }
    621 
    622 base::DictionaryValue* PreferenceSpecificsToValue(
    623     const sync_pb::PreferenceSpecifics& proto) {
    624   base::DictionaryValue* value = new base::DictionaryValue();
    625   SET_STR(name);
    626   SET_STR(value);
    627   return value;
    628 }
    629 
    630 base::DictionaryValue* PriorityPreferenceSpecificsToValue(
    631     const sync_pb::PriorityPreferenceSpecifics& specifics) {
    632   base::DictionaryValue* value = new base::DictionaryValue();
    633   SET_FIELD(preference, PreferenceSpecificsToValue);
    634   return value;
    635 }
    636 
    637 base::DictionaryValue* SyncedNotificationSpecificsToValue(
    638     const sync_pb::SyncedNotificationSpecifics& proto) {
    639   // There is a lot of data, for now just use heading, description, key, and
    640   // the read state.
    641   // TODO(petewil): Eventually add more data here.
    642   base::DictionaryValue* value = new base::DictionaryValue();
    643   SET(coalesced_notification, CoalescedNotificationToValue);
    644   return value;
    645 }
    646 
    647 base::DictionaryValue* SearchEngineSpecificsToValue(
    648     const sync_pb::SearchEngineSpecifics& proto) {
    649   base::DictionaryValue* value = new base::DictionaryValue();
    650   SET_STR(short_name);
    651   SET_STR(keyword);
    652   SET_STR(favicon_url);
    653   SET_STR(url);
    654   SET_BOOL(safe_for_autoreplace);
    655   SET_STR(originating_url);
    656   SET_INT64(date_created);
    657   SET_STR(input_encodings);
    658   SET_BOOL(show_in_default_list);
    659   SET_STR(suggestions_url);
    660   SET_INT32(prepopulate_id);
    661   SET_BOOL(autogenerate_keyword);
    662   SET_STR(instant_url);
    663   SET_INT64(last_modified);
    664   SET_STR(sync_guid);
    665   SET_STR_REP(alternate_urls);
    666   SET_STR(search_terms_replacement_key);
    667   SET_STR(image_url);
    668   SET_STR(search_url_post_params);
    669   SET_STR(suggestions_url_post_params);
    670   SET_STR(instant_url_post_params);
    671   SET_STR(image_url_post_params);
    672   SET_STR(new_tab_url);
    673   return value;
    674 }
    675 
    676 base::DictionaryValue* SessionSpecificsToValue(
    677     const sync_pb::SessionSpecifics& proto) {
    678   base::DictionaryValue* value = new base::DictionaryValue();
    679   SET_STR(session_tag);
    680   SET(header, SessionHeaderToValue);
    681   SET(tab, SessionTabToValue);
    682   SET_INT32(tab_node_id);
    683   return value;
    684 }
    685 
    686 base::DictionaryValue* ThemeSpecificsToValue(
    687     const sync_pb::ThemeSpecifics& proto) {
    688   base::DictionaryValue* value = new base::DictionaryValue();
    689   SET_BOOL(use_custom_theme);
    690   SET_BOOL(use_system_theme_by_default);
    691   SET_STR(custom_theme_name);
    692   SET_STR(custom_theme_id);
    693   SET_STR(custom_theme_update_url);
    694   return value;
    695 }
    696 
    697 base::DictionaryValue* TypedUrlSpecificsToValue(
    698     const sync_pb::TypedUrlSpecifics& proto) {
    699   base::DictionaryValue* value = new base::DictionaryValue();
    700   SET_STR(url);
    701   SET_STR(title);
    702   SET_BOOL(hidden);
    703   SET_INT64_REP(visits);
    704   SET_INT32_REP(visit_transitions);
    705   return value;
    706 }
    707 
    708 base::DictionaryValue* EntitySpecificsToValue(
    709     const sync_pb::EntitySpecifics& specifics) {
    710   base::DictionaryValue* value = new base::DictionaryValue();
    711   SET_FIELD(app, AppSpecificsToValue);
    712   SET_FIELD(app_list, AppListSpecificsToValue);
    713   SET_FIELD(app_notification, AppNotificationToValue);
    714   SET_FIELD(app_setting, AppSettingSpecificsToValue);
    715   SET_FIELD(article, ArticleSpecificsToValue);
    716   SET_FIELD(autofill, AutofillSpecificsToValue);
    717   SET_FIELD(autofill_profile, AutofillProfileSpecificsToValue);
    718   SET_FIELD(bookmark, BookmarkSpecificsToValue);
    719   SET_FIELD(device_info, DeviceInfoSpecificsToValue);
    720   SET_FIELD(dictionary, DictionarySpecificsToValue);
    721   SET_FIELD(experiments, ExperimentsSpecificsToValue);
    722   SET_FIELD(extension, ExtensionSpecificsToValue);
    723   SET_FIELD(extension_setting, ExtensionSettingSpecificsToValue);
    724   SET_FIELD(favicon_image, FaviconImageSpecificsToValue);
    725   SET_FIELD(favicon_tracking, FaviconTrackingSpecificsToValue);
    726   SET_FIELD(history_delete_directive, HistoryDeleteDirectiveSpecificsToValue);
    727   SET_FIELD(managed_user_setting, ManagedUserSettingSpecificsToValue);
    728   SET_FIELD(managed_user, ManagedUserSpecificsToValue);
    729   SET_FIELD(nigori, NigoriSpecificsToValue);
    730   SET_FIELD(password, PasswordSpecificsToValue);
    731   SET_FIELD(preference, PreferenceSpecificsToValue);
    732   SET_FIELD(priority_preference, PriorityPreferenceSpecificsToValue);
    733   SET_FIELD(search_engine, SearchEngineSpecificsToValue);
    734   SET_FIELD(session, SessionSpecificsToValue);
    735   SET_FIELD(synced_notification, SyncedNotificationSpecificsToValue);
    736   SET_FIELD(theme, ThemeSpecificsToValue);
    737   SET_FIELD(typed_url, TypedUrlSpecificsToValue);
    738   return value;
    739 }
    740 
    741 namespace {
    742 
    743 base::StringValue* UniquePositionToStringValue(
    744     const sync_pb::UniquePosition& proto) {
    745   UniquePosition pos = UniquePosition::FromProto(proto);
    746   return new base::StringValue(pos.ToDebugString());
    747 }
    748 
    749 base::DictionaryValue* SyncEntityToValue(const sync_pb::SyncEntity& proto,
    750                                          bool include_specifics) {
    751   base::DictionaryValue* value = new base::DictionaryValue();
    752   SET_STR(id_string);
    753   SET_STR(parent_id_string);
    754   SET_STR(old_parent_id);
    755   SET_INT64(version);
    756   SET_INT64(mtime);
    757   SET_INT64(ctime);
    758   SET_STR(name);
    759   SET_STR(non_unique_name);
    760   SET_INT64(sync_timestamp);
    761   SET_STR(server_defined_unique_tag);
    762   SET_INT64(position_in_parent);
    763   SET(unique_position, UniquePositionToStringValue);
    764   SET_STR(insert_after_item_id);
    765   SET_BOOL(deleted);
    766   SET_STR(originator_cache_guid);
    767   SET_STR(originator_client_item_id);
    768   if (include_specifics)
    769     SET(specifics, EntitySpecificsToValue);
    770   SET_BOOL(folder);
    771   SET_STR(client_defined_unique_tag);
    772   return value;
    773 }
    774 
    775 base::ListValue* SyncEntitiesToValue(
    776     const ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>& entities,
    777     bool include_specifics) {
    778   base::ListValue* list = new base::ListValue();
    779   ::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>::const_iterator it;
    780   for (it = entities.begin(); it != entities.end(); ++it) {
    781     list->Append(SyncEntityToValue(*it, include_specifics));
    782   }
    783 
    784   return list;
    785 }
    786 
    787 base::DictionaryValue* ChromiumExtensionActivityToValue(
    788     const sync_pb::ChromiumExtensionsActivity& proto) {
    789   base::DictionaryValue* value = new base::DictionaryValue();
    790   SET_STR(extension_id);
    791   SET_INT32(bookmark_writes_since_last_commit);
    792   return value;
    793 }
    794 
    795 base::DictionaryValue* CommitMessageToValue(
    796     const sync_pb::CommitMessage& proto,
    797     bool include_specifics) {
    798   base::DictionaryValue* value = new base::DictionaryValue();
    799   value->Set("entries",
    800              SyncEntitiesToValue(proto.entries(), include_specifics));
    801   SET_STR(cache_guid);
    802   SET_REP(extensions_activity, ChromiumExtensionActivityToValue);
    803   SET(config_params, ClientConfigParamsToValue);
    804   return value;
    805 }
    806 
    807 base::DictionaryValue* GetUpdateTriggersToValue(
    808     const sync_pb::GetUpdateTriggers& proto) {
    809   base::DictionaryValue* value = new base::DictionaryValue();
    810   SET_STR_REP(notification_hint);
    811   SET_BOOL(client_dropped_hints);
    812   SET_BOOL(invalidations_out_of_sync);
    813   SET_INT64(local_modification_nudges);
    814   SET_INT64(datatype_refresh_nudges);
    815   return value;
    816 }
    817 
    818 base::DictionaryValue* DataTypeProgressMarkerToValue(
    819     const sync_pb::DataTypeProgressMarker& proto) {
    820   base::DictionaryValue* value = new base::DictionaryValue();
    821   SET_INT32(data_type_id);
    822   SET_BYTES(token);
    823   SET_INT64(timestamp_token_for_migration);
    824   SET_STR(notification_hint);
    825   SET(get_update_triggers, GetUpdateTriggersToValue);
    826   return value;
    827 }
    828 
    829 base::DictionaryValue* GetUpdatesCallerInfoToValue(
    830     const sync_pb::GetUpdatesCallerInfo& proto) {
    831   base::DictionaryValue* value = new base::DictionaryValue();
    832   SET_ENUM(source, GetUpdatesSourceString);
    833   SET_BOOL(notifications_enabled);
    834   return value;
    835 }
    836 
    837 base::DictionaryValue* GetUpdatesMessageToValue(
    838     const sync_pb::GetUpdatesMessage& proto) {
    839   base::DictionaryValue* value = new base::DictionaryValue();
    840   SET(caller_info, GetUpdatesCallerInfoToValue);
    841   SET_BOOL(fetch_folders);
    842   SET_INT32(batch_size);
    843   SET_REP(from_progress_marker, DataTypeProgressMarkerToValue);
    844   SET_BOOL(streaming);
    845   SET_BOOL(need_encryption_key);
    846   SET_BOOL(create_mobile_bookmarks_folder);
    847   SET_ENUM(get_updates_origin, GetUpdatesOriginString);
    848   return value;
    849 }
    850 
    851 base::DictionaryValue* ClientStatusToValue(const sync_pb::ClientStatus& proto) {
    852   base::DictionaryValue* value = new base::DictionaryValue();
    853   SET_BOOL(hierarchy_conflict_detected);
    854   return value;
    855 }
    856 
    857 base::DictionaryValue* EntryResponseToValue(
    858     const sync_pb::CommitResponse::EntryResponse& proto) {
    859   base::DictionaryValue* value = new base::DictionaryValue();
    860   SET_ENUM(response_type, GetResponseTypeString);
    861   SET_STR(id_string);
    862   SET_STR(parent_id_string);
    863   SET_INT64(position_in_parent);
    864   SET_INT64(version);
    865   SET_STR(name);
    866   SET_STR(error_message);
    867   SET_INT64(mtime);
    868   return value;
    869 }
    870 
    871 base::DictionaryValue* CommitResponseToValue(
    872     const sync_pb::CommitResponse& proto) {
    873   base::DictionaryValue* value = new base::DictionaryValue();
    874   SET_REP(entryresponse, EntryResponseToValue);
    875   return value;
    876 }
    877 
    878 base::DictionaryValue* GetUpdatesResponseToValue(
    879     const sync_pb::GetUpdatesResponse& proto,
    880     bool include_specifics) {
    881   base::DictionaryValue* value = new base::DictionaryValue();
    882   value->Set("entries",
    883              SyncEntitiesToValue(proto.entries(), include_specifics));
    884   SET_INT64(changes_remaining);
    885   SET_REP(new_progress_marker, DataTypeProgressMarkerToValue);
    886   return value;
    887 }
    888 
    889 base::DictionaryValue* ClientCommandToValue(
    890     const sync_pb::ClientCommand& proto) {
    891   base::DictionaryValue* value = new base::DictionaryValue();
    892   SET_INT32(set_sync_poll_interval);
    893   SET_INT32(set_sync_long_poll_interval);
    894   SET_INT32(max_commit_batch_size);
    895   SET_INT32(sessions_commit_delay_seconds);
    896   SET_INT32(throttle_delay_seconds);
    897   SET_INT32(client_invalidation_hint_buffer_size);
    898   return value;
    899 }
    900 
    901 base::DictionaryValue* ErrorToValue(
    902     const sync_pb::ClientToServerResponse::Error& proto) {
    903   base::DictionaryValue* value = new base::DictionaryValue();
    904   SET_ENUM(error_type, GetErrorTypeString);
    905   SET_STR(error_description);
    906   SET_STR(url);
    907   SET_ENUM(action, GetActionString);
    908   return value;
    909 }
    910 
    911 }  // namespace
    912 
    913 base::DictionaryValue* ClientToServerResponseToValue(
    914     const sync_pb::ClientToServerResponse& proto,
    915     bool include_specifics) {
    916   base::DictionaryValue* value = new base::DictionaryValue();
    917   SET(commit, CommitResponseToValue);
    918   if (proto.has_get_updates()) {
    919     value->Set("get_updates", GetUpdatesResponseToValue(proto.get_updates(),
    920                                                         include_specifics));
    921   }
    922 
    923   SET(error, ErrorToValue);
    924   SET_ENUM(error_code, GetErrorTypeString);
    925   SET_STR(error_message);
    926   SET_STR(store_birthday);
    927   SET(client_command, ClientCommandToValue);
    928   SET_INT32_REP(migrated_data_type_id);
    929   return value;
    930 }
    931 
    932 base::DictionaryValue* ClientToServerMessageToValue(
    933     const sync_pb::ClientToServerMessage& proto,
    934     bool include_specifics) {
    935   base::DictionaryValue* value = new base::DictionaryValue();
    936   SET_STR(share);
    937   SET_INT32(protocol_version);
    938   if (proto.has_commit()) {
    939     value->Set("commit",
    940                CommitMessageToValue(proto.commit(), include_specifics));
    941   }
    942 
    943   SET(get_updates, GetUpdatesMessageToValue);
    944   SET_STR(store_birthday);
    945   SET_BOOL(sync_problem_detected);
    946   SET(debug_info, DebugInfoToValue);
    947   SET(client_status, ClientStatusToValue);
    948   return value;
    949 }
    950 
    951 base::DictionaryValue* DatatypeAssociationStatsToValue(
    952     const sync_pb::DatatypeAssociationStats& proto) {
    953   base::DictionaryValue* value = new base::DictionaryValue();
    954   SET_INT32(data_type_id);
    955   SET_INT32(num_local_items_before_association);
    956   SET_INT32(num_sync_items_before_association);
    957   SET_INT32(num_local_items_after_association);
    958   SET_INT32(num_sync_items_after_association);
    959   SET_INT32(num_local_items_added);
    960   SET_INT32(num_local_items_deleted);
    961   SET_INT32(num_local_items_modified);
    962   SET_INT32(num_sync_items_added);
    963   SET_INT32(num_sync_items_deleted);
    964   SET_INT32(num_sync_items_modified);
    965   SET_INT64(local_version_pre_association);
    966   SET_INT64(sync_version_pre_association)
    967   SET_BOOL(had_error);
    968   SET_INT64(download_wait_time_us);
    969   SET_INT64(download_time_us);
    970   SET_INT64(association_wait_time_for_high_priority_us);
    971   SET_INT64(association_wait_time_for_same_priority_us);
    972   return value;
    973 }
    974 
    975 base::DictionaryValue* DebugEventInfoToValue(
    976     const sync_pb::DebugEventInfo& proto) {
    977   base::DictionaryValue* value = new base::DictionaryValue();
    978   SET_ENUM(singleton_event, SingletonEventTypeString);
    979   SET(sync_cycle_completed_event_info, SyncCycleCompletedEventInfoToValue);
    980   SET_INT32(nudging_datatype);
    981   SET_INT32_REP(datatypes_notified_from_server);
    982   SET(datatype_association_stats, DatatypeAssociationStatsToValue);
    983   return value;
    984 }
    985 
    986 base::DictionaryValue* DebugInfoToValue(const sync_pb::DebugInfo& proto) {
    987   base::DictionaryValue* value = new base::DictionaryValue();
    988   SET_REP(events, DebugEventInfoToValue);
    989   SET_BOOL(cryptographer_ready);
    990   SET_BOOL(cryptographer_has_pending_keys);
    991   SET_BOOL(events_dropped);
    992   return value;
    993 }
    994 
    995 base::DictionaryValue* SyncCycleCompletedEventInfoToValue(
    996     const sync_pb::SyncCycleCompletedEventInfo& proto) {
    997   base::DictionaryValue* value = new base::DictionaryValue();
    998   SET_INT32(num_encryption_conflicts);
    999   SET_INT32(num_hierarchy_conflicts);
   1000   SET_INT32(num_server_conflicts);
   1001   SET_INT32(num_updates_downloaded);
   1002   SET_INT32(num_reflected_updates_downloaded);
   1003   SET(caller_info, GetUpdatesCallerInfoToValue);
   1004   return value;
   1005 }
   1006 
   1007 base::DictionaryValue* ClientConfigParamsToValue(
   1008     const sync_pb::ClientConfigParams& proto) {
   1009   base::DictionaryValue* value = new base::DictionaryValue();
   1010   SET_INT32_REP(enabled_type_ids);
   1011   SET_BOOL(tabs_datatype_enabled);
   1012   return value;
   1013 }
   1014 
   1015 #undef SET
   1016 #undef SET_REP
   1017 
   1018 #undef SET_BOOL
   1019 #undef SET_BYTES
   1020 #undef SET_INT32
   1021 #undef SET_INT64
   1022 #undef SET_INT64_REP
   1023 #undef SET_STR
   1024 #undef SET_STR_REP
   1025 
   1026 #undef SET_FIELD
   1027 
   1028 }  // namespace syncer
   1029