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