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