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