1 // Copyright (c) 2011 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 "chrome/browser/sync/protocol/proto_value_conversions.h"
8
9 #include "base/base64.h"
10 #include "base/basictypes.h"
11 #include "base/logging.h"
12 #include "base/string_number_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/sync/protocol/app_specifics.pb.h"
15 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
16 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
17 #include "chrome/browser/sync/protocol/encryption.pb.h"
18 #include "chrome/browser/sync/protocol/extension_specifics.pb.h"
19 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
20 #include "chrome/browser/sync/protocol/password_specifics.pb.h"
21 #include "chrome/browser/sync/protocol/preference_specifics.pb.h"
22 #include "chrome/browser/sync/protocol/proto_enum_conversions.h"
23 #include "chrome/browser/sync/protocol/session_specifics.pb.h"
24 #include "chrome/browser/sync/protocol/sync.pb.h"
25 #include "chrome/browser/sync/protocol/theme_specifics.pb.h"
26 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"
27
28 namespace browser_sync {
29
30 namespace {
31
32 // Basic Type -> Value functions.
33
MakeInt64Value(int64 x)34 StringValue* MakeInt64Value(int64 x) {
35 return Value::CreateStringValue(base::Int64ToString(x));
36 }
37
38 // TODO(akalin): Perhaps make JSONWriter support BinaryValue and use
39 // that instead of a StringValue.
MakeBytesValue(const std::string & bytes)40 StringValue* MakeBytesValue(const std::string& bytes) {
41 std::string bytes_base64;
42 if (!base::Base64Encode(bytes, &bytes_base64)) {
43 NOTREACHED();
44 }
45 return Value::CreateStringValue(bytes_base64);
46 }
47
48 // T is the enum type.
49 template <class T>
MakeEnumValue(T t,const char * (* converter_fn)(T))50 StringValue* MakeEnumValue(T t, const char* (*converter_fn)(T)) {
51 return Value::CreateStringValue(converter_fn(t));
52 }
53
54 // T is the field type, F is either RepeatedField or RepeatedPtrField,
55 // and V is a subclass of Value.
56 template <class T, class F, class V>
MakeRepeatedValue(const F & fields,V * (* converter_fn)(T))57 ListValue* MakeRepeatedValue(const F& fields, V* (*converter_fn)(T)) {
58 ListValue* list = new ListValue();
59 for (typename F::const_iterator it = fields.begin(); it != fields.end();
60 ++it) {
61 list->Append(converter_fn(*it));
62 }
63 return list;
64 }
65
66 } // namespace
67
68 // Helper macros to reduce the amount of boilerplate.
69
70 #define SET(field, fn) value->Set(#field, fn(proto.field()))
71 #define SET_REP(field, fn) \
72 value->Set(#field, MakeRepeatedValue(proto.field(), fn))
73 #define SET_ENUM(field, fn) \
74 value->Set(#field, MakeEnumValue(proto.field(), fn))
75
76 #define SET_BOOL(field) SET(field, Value::CreateBooleanValue)
77 #define SET_BYTES(field) SET(field, MakeBytesValue)
78 #define SET_INT32(field) SET(field, MakeInt64Value)
79 #define SET_INT32_REP(field) SET_REP(field, MakeInt64Value)
80 #define SET_INT64(field) SET(field, MakeInt64Value)
81 #define SET_INT64_REP(field) SET_REP(field, MakeInt64Value)
82 #define SET_STR(field) SET(field, Value::CreateStringValue)
83
84 #define SET_EXTENSION(ns, field, fn) \
85 do { \
86 if (specifics.HasExtension(ns::field)) { \
87 value->Set(#field, fn(specifics.GetExtension(ns::field))); \
88 } \
89 } while (0)
90
91 // If you add another macro, don't forget to add an #undef at the end
92 // of this file, too.
93
EncryptedDataToValue(const sync_pb::EncryptedData & proto)94 DictionaryValue* EncryptedDataToValue(const sync_pb::EncryptedData& proto) {
95 DictionaryValue* value = new DictionaryValue();
96 SET_STR(key_name);
97 // TODO(akalin): Shouldn't blob be of type bytes instead of string?
98 SET_BYTES(blob);
99 return value;
100 }
101
SessionHeaderToValue(const sync_pb::SessionHeader & proto)102 DictionaryValue* SessionHeaderToValue(
103 const sync_pb::SessionHeader& proto) {
104 DictionaryValue* value = new DictionaryValue();
105 SET_REP(window, SessionWindowToValue);
106 return value;
107 }
108
SessionTabToValue(const sync_pb::SessionTab & proto)109 DictionaryValue* SessionTabToValue(
110 const sync_pb::SessionTab& proto) {
111 DictionaryValue* value = new DictionaryValue();
112 SET_INT32(tab_id);
113 SET_INT32(window_id);
114 SET_INT32(tab_visual_index);
115 SET_INT32(current_navigation_index);
116 SET_BOOL(pinned);
117 SET_STR(extension_app_id);
118 SET_REP(navigation, TabNavigationToValue);
119 return value;
120 }
121
SessionWindowToValue(const sync_pb::SessionWindow & proto)122 DictionaryValue* SessionWindowToValue(
123 const sync_pb::SessionWindow& proto) {
124 DictionaryValue* value = new DictionaryValue();
125 SET_INT32(window_id);
126 SET_INT32(selected_tab_index);
127 SET_INT32_REP(tab);
128 SET_ENUM(browser_type, GetBrowserTypeString);
129 return value;
130 }
131
TabNavigationToValue(const sync_pb::TabNavigation & proto)132 DictionaryValue* TabNavigationToValue(
133 const sync_pb::TabNavigation& proto) {
134 DictionaryValue* value = new DictionaryValue();
135 SET_INT32(index);
136 SET_STR(virtual_url);
137 SET_STR(referrer);
138 SET_STR(title);
139 SET_STR(state);
140 SET_ENUM(page_transition, GetPageTransitionString);
141 SET_ENUM(navigation_qualifier, GetPageTransitionQualifierString);
142 return value;
143 }
144
PasswordSpecificsDataToValue(const sync_pb::PasswordSpecificsData & proto)145 DictionaryValue* PasswordSpecificsDataToValue(
146 const sync_pb::PasswordSpecificsData& proto) {
147 DictionaryValue* value = new DictionaryValue();
148 SET_INT32(scheme);
149 SET_STR(signon_realm);
150 SET_STR(origin);
151 SET_STR(action);
152 SET_STR(username_element);
153 SET_STR(username_value);
154 SET_STR(password_element);
155 value->SetString("password_value", "<redacted>");
156 SET_BOOL(ssl_valid);
157 SET_BOOL(preferred);
158 SET_INT64(date_created);
159 SET_BOOL(blacklisted);
160 return value;
161 }
162
AppSpecificsToValue(const sync_pb::AppSpecifics & proto)163 DictionaryValue* AppSpecificsToValue(
164 const sync_pb::AppSpecifics& proto) {
165 DictionaryValue* value = new DictionaryValue();
166 SET(extension, ExtensionSpecificsToValue);
167 return value;
168 }
169
AutofillSpecificsToValue(const sync_pb::AutofillSpecifics & proto)170 DictionaryValue* AutofillSpecificsToValue(
171 const sync_pb::AutofillSpecifics& proto) {
172 DictionaryValue* value = new DictionaryValue();
173 SET_STR(name);
174 SET_STR(value);
175 SET_INT64_REP(usage_timestamp);
176 SET(profile, AutofillProfileSpecificsToValue);
177 SET_BYTES(encrypted_credit_card);
178 SET(credit_card, AutofillCreditCardSpecificsToValue);
179 return value;
180 }
181
AutofillCreditCardSpecificsToValue(const sync_pb::AutofillCreditCardSpecifics & proto)182 DictionaryValue* AutofillCreditCardSpecificsToValue(
183 const sync_pb::AutofillCreditCardSpecifics& proto) {
184 DictionaryValue* value = new DictionaryValue();
185 SET_STR(label);
186 SET_STR(name_on_card);
187 SET_STR(type);
188 SET_STR(card_number);
189 SET_STR(expiration_month);
190 SET_STR(expiration_year);
191 SET_STR(verification_code);
192 SET_STR(billing_address);
193 SET_STR(shipping_address);
194 return value;
195 }
196
AutofillProfileSpecificsToValue(const sync_pb::AutofillProfileSpecifics & proto)197 DictionaryValue* AutofillProfileSpecificsToValue(
198 const sync_pb::AutofillProfileSpecifics& proto) {
199 DictionaryValue* value = new DictionaryValue();
200 SET_STR(label);
201 SET_STR(guid);
202
203 SET_STR(name_first);
204 SET_STR(name_middle);
205 SET_STR(name_last);
206 SET_STR(email_address);
207 SET_STR(company_name);
208
209 SET_STR(address_home_line1);
210 SET_STR(address_home_line2);
211 SET_STR(address_home_city);
212 SET_STR(address_home_state);
213 SET_STR(address_home_zip);
214 SET_STR(address_home_country);
215
216 SET_STR(phone_home_whole_number);
217 SET_STR(phone_fax_whole_number);
218 return value;
219 }
220
BookmarkSpecificsToValue(const sync_pb::BookmarkSpecifics & proto)221 DictionaryValue* BookmarkSpecificsToValue(
222 const sync_pb::BookmarkSpecifics& proto) {
223 DictionaryValue* value = new DictionaryValue();
224 SET_STR(url);
225 SET_BYTES(favicon);
226 return value;
227 }
228
ExtensionSpecificsToValue(const sync_pb::ExtensionSpecifics & proto)229 DictionaryValue* ExtensionSpecificsToValue(
230 const sync_pb::ExtensionSpecifics& proto) {
231 DictionaryValue* value = new DictionaryValue();
232 SET_STR(id);
233 SET_STR(version);
234 SET_STR(update_url);
235 SET_BOOL(enabled);
236 SET_BOOL(incognito_enabled);
237 SET_STR(name);
238 return value;
239 }
240
NigoriSpecificsToValue(const sync_pb::NigoriSpecifics & proto)241 DictionaryValue* NigoriSpecificsToValue(
242 const sync_pb::NigoriSpecifics& proto) {
243 DictionaryValue* value = new DictionaryValue();
244 SET(encrypted, EncryptedDataToValue);
245 SET_BOOL(using_explicit_passphrase);
246 return value;
247 }
248
PasswordSpecificsToValue(const sync_pb::PasswordSpecifics & proto)249 DictionaryValue* PasswordSpecificsToValue(
250 const sync_pb::PasswordSpecifics& proto) {
251 DictionaryValue* value = new DictionaryValue();
252 SET(encrypted, EncryptedDataToValue);
253 return value;
254 }
255
PreferenceSpecificsToValue(const sync_pb::PreferenceSpecifics & proto)256 DictionaryValue* PreferenceSpecificsToValue(
257 const sync_pb::PreferenceSpecifics& proto) {
258 DictionaryValue* value = new DictionaryValue();
259 SET_STR(name);
260 SET_STR(value);
261 return value;
262 }
263
SessionSpecificsToValue(const sync_pb::SessionSpecifics & proto)264 DictionaryValue* SessionSpecificsToValue(
265 const sync_pb::SessionSpecifics& proto) {
266 DictionaryValue* value = new DictionaryValue();
267 SET_STR(session_tag);
268 SET(header, SessionHeaderToValue);
269 SET(tab, SessionTabToValue);
270 return value;
271 }
272
ThemeSpecificsToValue(const sync_pb::ThemeSpecifics & proto)273 DictionaryValue* ThemeSpecificsToValue(
274 const sync_pb::ThemeSpecifics& proto) {
275 DictionaryValue* value = new DictionaryValue();
276 SET_BOOL(use_custom_theme);
277 SET_BOOL(use_system_theme_by_default);
278 SET_STR(custom_theme_name);
279 SET_STR(custom_theme_id);
280 SET_STR(custom_theme_update_url);
281 return value;
282 }
283
TypedUrlSpecificsToValue(const sync_pb::TypedUrlSpecifics & proto)284 DictionaryValue* TypedUrlSpecificsToValue(
285 const sync_pb::TypedUrlSpecifics& proto) {
286 DictionaryValue* value = new DictionaryValue();
287 SET_STR(url);
288 SET_STR(title);
289 SET_INT32(typed_count);
290 SET_BOOL(hidden);
291 SET_INT64_REP(visit);
292 return value;
293 }
294
EntitySpecificsToValue(const sync_pb::EntitySpecifics & specifics)295 DictionaryValue* EntitySpecificsToValue(
296 const sync_pb::EntitySpecifics& specifics) {
297 DictionaryValue* value = new DictionaryValue();
298 SET_EXTENSION(sync_pb, app, AppSpecificsToValue);
299 SET_EXTENSION(sync_pb, autofill, AutofillSpecificsToValue);
300 SET_EXTENSION(sync_pb, autofill_profile, AutofillProfileSpecificsToValue);
301 SET_EXTENSION(sync_pb, bookmark, BookmarkSpecificsToValue);
302 SET_EXTENSION(sync_pb, extension, ExtensionSpecificsToValue);
303 SET_EXTENSION(sync_pb, nigori, NigoriSpecificsToValue);
304 SET_EXTENSION(sync_pb, password, PasswordSpecificsToValue);
305 SET_EXTENSION(sync_pb, preference, PreferenceSpecificsToValue);
306 SET_EXTENSION(sync_pb, session, SessionSpecificsToValue);
307 SET_EXTENSION(sync_pb, theme, ThemeSpecificsToValue);
308 SET_EXTENSION(sync_pb, typed_url, TypedUrlSpecificsToValue);
309 return value;
310 }
311
312 #undef SET
313 #undef SET_REP
314
315 #undef SET_BOOL
316 #undef SET_BYTES
317 #undef SET_INT32
318 #undef SET_INT64
319 #undef SET_INT64_REP
320 #undef SET_STR
321
322 #undef SET_EXTENSION
323
324 } // namespace browser_sync
325