diff options
20 files changed, 770 insertions, 0 deletions
diff --git a/chrome/browser/sync/protocol/app_specifics.proto b/chrome/browser/sync/protocol/app_specifics.proto index 452cc50..4bfc225 100644 --- a/chrome/browser/sync/protocol/app_specifics.proto +++ b/chrome/browser/sync/protocol/app_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for apps. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/autofill_specifics.proto b/chrome/browser/sync/protocol/autofill_specifics.proto index 536623c..520f25f 100644 --- a/chrome/browser/sync/protocol/autofill_specifics.proto +++ b/chrome/browser/sync/protocol/autofill_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for autofill. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/bookmark_specifics.proto b/chrome/browser/sync/protocol/bookmark_specifics.proto index c94fd2e..75321f8 100644 --- a/chrome/browser/sync/protocol/bookmark_specifics.proto +++ b/chrome/browser/sync/protocol/bookmark_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for bookmarks. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/encryption.proto b/chrome/browser/sync/protocol/encryption.proto index 6d6a792..da51ff0 100644 --- a/chrome/browser/sync/protocol/encryption.proto +++ b/chrome/browser/sync/protocol/encryption.proto @@ -4,6 +4,9 @@ // // Common sync protocol for encrypted data. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/extension_specifics.proto b/chrome/browser/sync/protocol/extension_specifics.proto index dff29b2..25b98a0 100644 --- a/chrome/browser/sync/protocol/extension_specifics.proto +++ b/chrome/browser/sync/protocol/extension_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for extensions. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/nigori_specifics.proto b/chrome/browser/sync/protocol/nigori_specifics.proto index e7458c6..98ee1b7 100644 --- a/chrome/browser/sync/protocol/nigori_specifics.proto +++ b/chrome/browser/sync/protocol/nigori_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for nigori keys. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/password_specifics.proto b/chrome/browser/sync/protocol/password_specifics.proto index 210ec6e..49f1343 100644 --- a/chrome/browser/sync/protocol/password_specifics.proto +++ b/chrome/browser/sync/protocol/password_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for password data. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/preference_specifics.proto b/chrome/browser/sync/protocol/preference_specifics.proto index 8e221444..72bc375 100644 --- a/chrome/browser/sync/protocol/preference_specifics.proto +++ b/chrome/browser/sync/protocol/preference_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for preferences. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/proto_enum_conversions.cc b/chrome/browser/sync/protocol/proto_enum_conversions.cc new file mode 100644 index 0000000..7421711 --- /dev/null +++ b/chrome/browser/sync/protocol/proto_enum_conversions.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Keep this file in sync with the .proto files in this directory. + +#include "chrome/browser/sync/protocol/proto_enum_conversions.h" + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace browser_sync { + +#define ASSERT_ENUM_BOUNDS(enum_parent, enum_type, enum_min, enum_max) \ + COMPILE_ASSERT(enum_parent::enum_type##_MIN == enum_parent::enum_min, \ + enum_type##_MIN_not_##enum_min); \ + COMPILE_ASSERT(enum_parent::enum_type##_MAX == enum_parent::enum_max, \ + enum_type##_MAX_not_##enum_max); + +#define ENUM_CASE(enum_parent, enum_value) \ + case enum_parent::enum_value: return #enum_value + +const char* GetBrowserTypeString( + sync_pb::SessionWindow::BrowserType browser_type) { + ASSERT_ENUM_BOUNDS(sync_pb::SessionWindow, BrowserType, + TYPE_NORMAL, TYPE_POPUP); + switch (browser_type) { + ENUM_CASE(sync_pb::SessionWindow, TYPE_NORMAL); + ENUM_CASE(sync_pb::SessionWindow, TYPE_POPUP); + } + NOTREACHED(); + return ""; +} + +const char* GetPageTransitionString( + sync_pb::TabNavigation::PageTransition page_transition) { + ASSERT_ENUM_BOUNDS(sync_pb::TabNavigation, PageTransition, + LINK, CHAIN_END); + switch (page_transition) { + ENUM_CASE(sync_pb::TabNavigation, LINK); + ENUM_CASE(sync_pb::TabNavigation, TYPED); + ENUM_CASE(sync_pb::TabNavigation, AUTO_BOOKMARK); + ENUM_CASE(sync_pb::TabNavigation, AUTO_SUBFRAME); + ENUM_CASE(sync_pb::TabNavigation, MANUAL_SUBFRAME); + ENUM_CASE(sync_pb::TabNavigation, GENERATED); + ENUM_CASE(sync_pb::TabNavigation, START_PAGE); + ENUM_CASE(sync_pb::TabNavigation, FORM_SUBMIT); + ENUM_CASE(sync_pb::TabNavigation, RELOAD); + ENUM_CASE(sync_pb::TabNavigation, KEYWORD); + ENUM_CASE(sync_pb::TabNavigation, KEYWORD_GENERATED); + ENUM_CASE(sync_pb::TabNavigation, CHAIN_START); + ENUM_CASE(sync_pb::TabNavigation, CHAIN_END); + } + NOTREACHED(); + return ""; +} + +const char* GetPageTransitionQualifierString( + sync_pb::TabNavigation::PageTransitionQualifier + page_transition_qualifier) { + ASSERT_ENUM_BOUNDS(sync_pb::TabNavigation, PageTransitionQualifier, + CLIENT_REDIRECT, SERVER_REDIRECT); + switch (page_transition_qualifier) { + ENUM_CASE(sync_pb::TabNavigation, CLIENT_REDIRECT); + ENUM_CASE(sync_pb::TabNavigation, SERVER_REDIRECT); + } + NOTREACHED(); + return ""; +} + +#undef ASSERT_ENUM_BOUNDS +#undef ENUM_CASE + +} // namespace diff --git a/chrome/browser/sync/protocol/proto_enum_conversions.h b/chrome/browser/sync/protocol/proto_enum_conversions.h new file mode 100644 index 0000000..62b6157 --- /dev/null +++ b/chrome/browser/sync/protocol/proto_enum_conversions.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SYNC_PROTOCOL_PROTO_ENUM_CONVERSIONS_H_ +#define CHROME_BROWSER_SYNC_PROTOCOL_PROTO_ENUM_CONVERSIONS_H_ +#pragma once + +// Keep this file in sync with the .proto files in this directory. + +#include "chrome/browser/sync/protocol/session_specifics.pb.h" + +// Utility functions to get the string equivalent for some sync proto +// enums. + +namespace browser_sync { + +// The returned strings (which don't have to be freed) are in ASCII. +// The result of passing in an invalid enum value is undefined. + +const char* GetBrowserTypeString( + sync_pb::SessionWindow::BrowserType browser_type); + +const char* GetPageTransitionString( + sync_pb::TabNavigation::PageTransition page_transition); + +const char* GetPageTransitionQualifierString( + sync_pb::TabNavigation::PageTransitionQualifier + page_transition_qualifier); + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_PROTOCOL_PROTO_ENUM_CONVERSIONS_H_ diff --git a/chrome/browser/sync/protocol/proto_enum_conversions_unittest.cc b/chrome/browser/sync/protocol/proto_enum_conversions_unittest.cc new file mode 100644 index 0000000..8825458 --- /dev/null +++ b/chrome/browser/sync/protocol/proto_enum_conversions_unittest.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Keep this file in sync with the .proto files in this directory. + +#include "chrome/browser/sync/protocol/proto_enum_conversions.h" + +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace browser_sync { +namespace { + +class ProtoEnumConversionsTest : public testing::Test { +}; + +template <class T> +void TestEnumStringFunction(const char* (*enum_string_fn)(T), + int enum_min, int enum_max) { + for (int i = enum_min; i <= enum_max; ++i) { + const std::string& str = enum_string_fn(static_cast<T>(i)); + EXPECT_FALSE(str.empty()); + } +} + +TEST_F(ProtoEnumConversionsTest, GetBrowserTypeString) { + TestEnumStringFunction( + GetBrowserTypeString, + sync_pb::SessionWindow::BrowserType_MIN, + sync_pb::SessionWindow::BrowserType_MAX); +} + +TEST_F(ProtoEnumConversionsTest, GetPageTransitionString) { + // We have a gap, so we need to do two ranges. + TestEnumStringFunction( + GetPageTransitionString, + sync_pb::TabNavigation::PageTransition_MIN, + sync_pb::TabNavigation::KEYWORD_GENERATED); + TestEnumStringFunction( + GetPageTransitionString, + sync_pb::TabNavigation::CHAIN_START, + sync_pb::TabNavigation::PageTransition_MAX); +} + +TEST_F(ProtoEnumConversionsTest, GetPageTransitionQualifierString) { + TestEnumStringFunction( + GetPageTransitionQualifierString, + sync_pb::TabNavigation::PageTransitionQualifier_MIN, + sync_pb::TabNavigation::PageTransitionQualifier_MAX); +} + +} // namespace +} // namespace browser_sync diff --git a/chrome/browser/sync/protocol/proto_value_conversions.cc b/chrome/browser/sync/protocol/proto_value_conversions.cc new file mode 100644 index 0000000..57be094 --- /dev/null +++ b/chrome/browser/sync/protocol/proto_value_conversions.cc @@ -0,0 +1,306 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Keep this file in sync with the .proto files in this directory. + +#include "chrome/browser/sync/protocol/proto_value_conversions.h" + +#include "base/base64.h" +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/string_number_conversions.h" +#include "base/values.h" +#include "chrome/browser/sync/protocol/app_specifics.pb.h" +#include "chrome/browser/sync/protocol/autofill_specifics.pb.h" +#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" +#include "chrome/browser/sync/protocol/encryption.pb.h" +#include "chrome/browser/sync/protocol/extension_specifics.pb.h" +#include "chrome/browser/sync/protocol/nigori_specifics.pb.h" +#include "chrome/browser/sync/protocol/password_specifics.pb.h" +#include "chrome/browser/sync/protocol/preference_specifics.pb.h" +#include "chrome/browser/sync/protocol/proto_enum_conversions.h" +#include "chrome/browser/sync/protocol/session_specifics.pb.h" +#include "chrome/browser/sync/protocol/sync.pb.h" +#include "chrome/browser/sync/protocol/theme_specifics.pb.h" +#include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" + +namespace browser_sync { + +namespace { + +// Basic Type -> Value functions. + +StringValue* MakeInt64Value(int64 x) { + return Value::CreateStringValue(base::Int64ToString(x)); +} + +// TODO(akalin): Perhaps make JSONWriter support BinaryValue and use +// that instead of a StringValue. +StringValue* MakeBytesValue(const std::string& bytes) { + std::string bytes_base64; + if (!base::Base64Encode(bytes, &bytes_base64)) { + NOTREACHED(); + } + return Value::CreateStringValue(bytes_base64); +} + +// T is the enum type. +template <class T> +StringValue* MakeEnumValue(T t, const char* (*converter_fn)(T)) { + return Value::CreateStringValue(converter_fn(t)); +} + +// T is the field type, F is either RepeatedField or RepeatedPtrField, +// and V is a subclass of Value. +template <class T, class F, class V> +ListValue* MakeRepeatedValue(const F& fields, V* (*converter_fn)(T)) { + ListValue* list = new ListValue(); + for (typename F::const_iterator it = fields.begin(); it != fields.end(); + ++it) { + list->Append(converter_fn(*it)); + } + return list; +} + +} // namespace + +// Helper macros to reduce the amount of boilerplate. + +#define SET(field, fn) value->Set(#field, fn(proto.field())) +#define SET_REP(field, fn) \ + value->Set(#field, MakeRepeatedValue(proto.field(), fn)) +#define SET_ENUM(field, fn) \ + value->Set(#field, MakeEnumValue(proto.field(), fn)) + +#define SET_BOOL(field) SET(field, Value::CreateBooleanValue) +#define SET_BYTES(field) SET(field, MakeBytesValue) +#define SET_INT32(field) SET(field, MakeInt64Value) +#define SET_INT32_REP(field) SET_REP(field, MakeInt64Value) +#define SET_INT64(field) SET(field, MakeInt64Value) +#define SET_INT64_REP(field) SET_REP(field, MakeInt64Value) +#define SET_STR(field) SET(field, Value::CreateStringValue) + +#define SET_EXTENSION(ns, field, fn) \ + do { \ + if (specifics.HasExtension(ns::field)) { \ + value->Set(#field, fn(specifics.GetExtension(ns::field))); \ + } \ + } while (0) + +// If you add another macro, don't forget to add an #undef at the end +// of this file, too. + +DictionaryValue* EncryptedDataToValue(const sync_pb::EncryptedData& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(key_name); + // TODO(akalin): Shouldn't blob be of type bytes instead of string? + SET_BYTES(blob); + return value; +} + +DictionaryValue* AppSpecificsToValue( + const sync_pb::AppSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET(extension, ExtensionSpecificsToValue); + return value; +} + +DictionaryValue* AutofillSpecificsToValue( + const sync_pb::AutofillSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(name); + SET_STR(value); + SET_INT64_REP(usage_timestamp); + SET(profile, AutofillProfileSpecificsToValue); + SET_BYTES(encrypted_credit_card); + SET(credit_card, AutofillCreditCardSpecificsToValue); + return value; +} + +DictionaryValue* AutofillCreditCardSpecificsToValue( + const sync_pb::AutofillCreditCardSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(label); + SET_STR(name_on_card); + SET_STR(type); + SET_STR(card_number); + SET_STR(expiration_month); + SET_STR(expiration_year); + SET_STR(verification_code); + SET_STR(billing_address); + SET_STR(shipping_address); + return value; +} + +DictionaryValue* AutofillProfileSpecificsToValue( + const sync_pb::AutofillProfileSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(label); + SET_STR(guid); + + SET_STR(name_first); + SET_STR(name_middle); + SET_STR(name_last); + SET_STR(email_address); + SET_STR(company_name); + + SET_STR(address_home_line1); + SET_STR(address_home_line2); + SET_STR(address_home_city); + SET_STR(address_home_state); + SET_STR(address_home_zip); + SET_STR(address_home_country); + + SET_STR(phone_home_whole_number); + SET_STR(phone_fax_whole_number); + return value; +} + +DictionaryValue* BookmarkSpecificsToValue( + const sync_pb::BookmarkSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(url); + SET_BYTES(favicon); + return value; +} + +DictionaryValue* ExtensionSpecificsToValue( + const sync_pb::ExtensionSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(id); + SET_STR(version); + SET_STR(update_url); + SET_BOOL(enabled); + SET_BOOL(incognito_enabled); + SET_STR(name); + return value; +} + +DictionaryValue* NigoriSpecificsToValue( + const sync_pb::NigoriSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET(encrypted, EncryptedDataToValue); + SET_BOOL(using_explicit_passphrase); + return value; +} + +DictionaryValue* PasswordSpecificsToValue( + const sync_pb::PasswordSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET(encrypted, EncryptedDataToValue); + return value; +} + +DictionaryValue* PreferenceSpecificsToValue( + const sync_pb::PreferenceSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(name); + SET_STR(value); + return value; +} + +DictionaryValue* SessionHeaderToValue( + const sync_pb::SessionHeader& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_REP(window, SessionWindowToValue); + return value; +} + +DictionaryValue* SessionTabToValue( + const sync_pb::SessionTab& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_INT32(tab_id); + SET_INT32(window_id); + SET_INT32(tab_visual_index); + SET_INT32(current_navigation_index); + SET_BOOL(pinned); + SET_STR(extension_app_id); + SET_REP(navigation, TabNavigationToValue); + return value; +} + +DictionaryValue* SessionWindowToValue( + const sync_pb::SessionWindow& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_INT32(window_id); + SET_INT32(selected_tab_index); + SET_INT32_REP(tab); + SET_ENUM(browser_type, GetBrowserTypeString); + return value; +} + +DictionaryValue* TabNavigationToValue( + const sync_pb::TabNavigation& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_INT32(index); + SET_STR(virtual_url); + SET_STR(referrer); + SET_STR(title); + SET_STR(state); + SET_ENUM(page_transition, GetPageTransitionString); + SET_ENUM(navigation_qualifier, GetPageTransitionQualifierString); + return value; +} + +DictionaryValue* SessionSpecificsToValue( + const sync_pb::SessionSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(session_tag); + SET(header, SessionHeaderToValue); + SET(tab, SessionTabToValue); + return value; +} + +DictionaryValue* ThemeSpecificsToValue( + const sync_pb::ThemeSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_BOOL(use_custom_theme); + SET_BOOL(use_system_theme_by_default); + SET_STR(custom_theme_name); + SET_STR(custom_theme_id); + SET_STR(custom_theme_update_url); + return value; +} + +DictionaryValue* TypedUrlSpecificsToValue( + const sync_pb::TypedUrlSpecifics& proto) { + DictionaryValue* value = new DictionaryValue(); + SET_STR(url); + SET_STR(title); + SET_INT32(typed_count); + SET_BOOL(hidden); + SET_INT64_REP(visit); + return value; +} + +DictionaryValue* EntitySpecificsToValue( + const sync_pb::EntitySpecifics& specifics) { + DictionaryValue* value = new DictionaryValue(); + SET_EXTENSION(sync_pb, app, AppSpecificsToValue); + SET_EXTENSION(sync_pb, autofill, AutofillSpecificsToValue); + SET_EXTENSION(sync_pb, autofill_profile, AutofillProfileSpecificsToValue); + SET_EXTENSION(sync_pb, bookmark, BookmarkSpecificsToValue); + SET_EXTENSION(sync_pb, extension, ExtensionSpecificsToValue); + SET_EXTENSION(sync_pb, nigori, NigoriSpecificsToValue); + SET_EXTENSION(sync_pb, password, PasswordSpecificsToValue); + SET_EXTENSION(sync_pb, preference, PreferenceSpecificsToValue); + SET_EXTENSION(sync_pb, session, SessionSpecificsToValue); + SET_EXTENSION(sync_pb, theme, ThemeSpecificsToValue); + SET_EXTENSION(sync_pb, typed_url, TypedUrlSpecificsToValue); + return value; +} + +#undef SET +#undef SET_REP + +#undef SET_BOOL +#undef SET_BYTES +#undef SET_INT32 +#undef SET_INT64 +#undef SET_INT64_REP +#undef SET_STR + +#undef SET_EXTENSION + +} // namespace browser_sync diff --git a/chrome/browser/sync/protocol/proto_value_conversions.h b/chrome/browser/sync/protocol/proto_value_conversions.h new file mode 100644 index 0000000..b28fd12 --- /dev/null +++ b/chrome/browser/sync/protocol/proto_value_conversions.h @@ -0,0 +1,109 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Keep this file in sync with the .proto files in this directory. + +#ifndef CHROME_BROWSER_SYNC_PROTOCOL_PROTO_VALUE_CONVERSIONS_H_ +#define CHROME_BROWSER_SYNC_PROTOCOL_PROTO_VALUE_CONVERSIONS_H_ +#pragma once + +class DictionaryValue; + +namespace sync_pb { +class AppSpecifics; +class AutofillCreditCardSpecifics; +class AutofillProfileSpecifics; +class AutofillSpecifics; +class BookmarkSpecifics; +class EncryptedData; +class EntitySpecifics; +class ExtensionSpecifics; +class NigoriSpecifics; +class PasswordSpecifics; +class PreferenceSpecifics; +class SessionHeader; +class SessionSpecifics; +class SessionTab; +class SessionWindow; +class TabNavigation; +class ThemeSpecifics; +class TypedUrlSpecifics; +} // namespace sync_pb + +// Utility functions to convert sync protocol buffers to dictionaries. +// Each protocol field is mapped to a key of the same name. Repeated +// fields are mapped to array values and sub-messages are mapped to +// sub-dictionary values. +// +// TODO(akalin): Add has_* information. +// +// TODO(akalin): Improve enum support. + +namespace browser_sync { + +// TODO(akalin): Perhaps extend this to decrypt? +DictionaryValue* EncryptedDataToValue( + const sync_pb::EncryptedData& encrypted_data); + +// Sub-protocols of SessionSpecifics. + +DictionaryValue* SessionHeaderToValue( + const sync_pb::SessionHeader& session_header); + +DictionaryValue* SessionTabToValue( + const sync_pb::SessionTab& session_tab); + +DictionaryValue* SessionWindowToValue( + const sync_pb::SessionWindow& session_window); + +DictionaryValue* TabNavigationToValue( + const sync_pb::TabNavigation& tab_navigation); + +// Main *SpecificsToValue functions. + +DictionaryValue* AppSpecificsToValue( + const sync_pb::AppSpecifics& app_specifics); + +DictionaryValue* AutofillSpecificsToValue( + const sync_pb::AutofillSpecifics& autofill_specifics); + +DictionaryValue* AutofillCreditCardSpecificsToValue( + const sync_pb::AutofillCreditCardSpecifics& + autofill_credit_card_specifics); + +DictionaryValue* AutofillProfileSpecificsToValue( + const sync_pb::AutofillProfileSpecifics& autofill_profile_specifics); + +DictionaryValue* BookmarkSpecificsToValue( + const sync_pb::BookmarkSpecifics& bookmark_specifics); + +DictionaryValue* ExtensionSpecificsToValue( + const sync_pb::ExtensionSpecifics& extension_specifics); + +DictionaryValue* NigoriSpecificsToValue( + const sync_pb::NigoriSpecifics& nigori_specifics); + +DictionaryValue* PasswordSpecificsToValue( + const sync_pb::PasswordSpecifics& password_specifics); + +DictionaryValue* PreferenceSpecificsToValue( + const sync_pb::PreferenceSpecifics& password_specifics); + +DictionaryValue* SessionSpecificsToValue( + const sync_pb::SessionSpecifics& session_specifics); + +DictionaryValue* ThemeSpecificsToValue( + const sync_pb::ThemeSpecifics& theme_specifics); + +DictionaryValue* TypedUrlSpecificsToValue( + const sync_pb::TypedUrlSpecifics& typed_url_specifics); + +// Any present extensions are mapped to sub-dictionary values with the +// key equal to the extension name. +DictionaryValue* EntitySpecificsToValue( + const sync_pb::EntitySpecifics& entity_specifics); + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_PROTOCOL_PROTO_VALUE_CONVERSIONS_H_ diff --git a/chrome/browser/sync/protocol/proto_value_conversions_unittest.cc b/chrome/browser/sync/protocol/proto_value_conversions_unittest.cc new file mode 100644 index 0000000..3416282 --- /dev/null +++ b/chrome/browser/sync/protocol/proto_value_conversions_unittest.cc @@ -0,0 +1,151 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Keep this file in sync with the .proto files in this directory. + +#include "chrome/browser/sync/protocol/proto_value_conversions.h" + +#include "base/scoped_ptr.h" +#include "base/values.h" +#include "chrome/browser/sync/protocol/app_specifics.pb.h" +#include "chrome/browser/sync/protocol/autofill_specifics.pb.h" +#include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" +#include "chrome/browser/sync/protocol/encryption.pb.h" +#include "chrome/browser/sync/protocol/extension_specifics.pb.h" +#include "chrome/browser/sync/protocol/nigori_specifics.pb.h" +#include "chrome/browser/sync/protocol/password_specifics.pb.h" +#include "chrome/browser/sync/protocol/preference_specifics.pb.h" +#include "chrome/browser/sync/protocol/session_specifics.pb.h" +#include "chrome/browser/sync/protocol/sync.pb.h" +#include "chrome/browser/sync/protocol/theme_specifics.pb.h" +#include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" +#include "chrome/browser/sync/syncable/model_type.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace browser_sync { +namespace { + +class ProtoValueConversionsTest : public testing::Test { + protected: + template <class T> + void TestSpecificsToValue( + DictionaryValue* (*specifics_to_value)(const T&)) { + const T& specifics(T::default_instance()); + scoped_ptr<DictionaryValue> value(specifics_to_value(specifics)); + // We can't do much but make sure that the returned value has + // something in it. + EXPECT_FALSE(value->empty()); + } +}; + +TEST_F(ProtoValueConversionsTest, ProtoChangeCheck) { + // If this number changes, that means we added or removed a data + // type. Don't forget to add a unit test for {New + // type}SpecificsToValue below. + EXPECT_EQ(13, syncable::MODEL_TYPE_COUNT); + + // We'd also like to check if we changed any field in our messages. + // However, that's hard to do: sizeof could work, but it's + // platform-dependent. default_instance().ByteSize() won't change + // for most changes, since most of our fields are optional. So we + // just settle for comments in the proto files. +} + +TEST_F(ProtoValueConversionsTest, EncryptedDataToValue) { + TestSpecificsToValue(EncryptedDataToValue); +} + +TEST_F(ProtoValueConversionsTest, AppSpecificsToValue) { + TestSpecificsToValue(AppSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, AutofillSpecificsToValue) { + TestSpecificsToValue(AutofillSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, AutofillCreditCardSpecificsToValue) { + TestSpecificsToValue(AutofillCreditCardSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, AutofillProfileSpecificsToValue) { + TestSpecificsToValue(AutofillProfileSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, BookmarkSpecificsToValue) { + TestSpecificsToValue(BookmarkSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, ExtensionSpecificsToValue) { + TestSpecificsToValue(ExtensionSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, NigoriSpecificsToValue) { + TestSpecificsToValue(NigoriSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, PasswordSpecificsToValue) { + TestSpecificsToValue(PasswordSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, PreferenceSpecificsToValue) { + TestSpecificsToValue(PreferenceSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, SessionHeaderToValue) { + TestSpecificsToValue(SessionHeaderToValue); +} + +TEST_F(ProtoValueConversionsTest, SessionSpecificsToValue) { + TestSpecificsToValue(SessionSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, SessionTabToValue) { + TestSpecificsToValue(SessionTabToValue); +} + +TEST_F(ProtoValueConversionsTest, SessionWindowToValue) { + TestSpecificsToValue(SessionWindowToValue); +} + +TEST_F(ProtoValueConversionsTest, TabNavigationToValue) { + TestSpecificsToValue(TabNavigationToValue); +} + +TEST_F(ProtoValueConversionsTest, ThemeSpecificsToValue) { + TestSpecificsToValue(ThemeSpecificsToValue); +} + +TEST_F(ProtoValueConversionsTest, TypedUrlSpecificsToValue) { + TestSpecificsToValue(TypedUrlSpecificsToValue); +} + +// TODO(akalin): Figure out how to better test EntitySpecificsToValue. + +TEST_F(ProtoValueConversionsTest, EntitySpecificsToValue) { + sync_pb::EntitySpecifics specifics; + // Touch the extensions to make sure it shows up in the generated + // value. +#define SET_EXTENSION(key) (void)specifics.MutableExtension(sync_pb::key) + + SET_EXTENSION(app); + SET_EXTENSION(autofill); + SET_EXTENSION(autofill_profile); + SET_EXTENSION(bookmark); + SET_EXTENSION(extension); + SET_EXTENSION(nigori); + SET_EXTENSION(password); + SET_EXTENSION(preference); + SET_EXTENSION(session); + SET_EXTENSION(theme); + SET_EXTENSION(typed_url); + +#undef SET_EXTENSION + + scoped_ptr<DictionaryValue> value(EntitySpecificsToValue(specifics)); + EXPECT_EQ(syncable::MODEL_TYPE_COUNT - syncable::FIRST_REAL_MODEL_TYPE, + static_cast<int>(value->size())); +} + +} // namespace +} // namespace browser_sync diff --git a/chrome/browser/sync/protocol/session_specifics.proto b/chrome/browser/sync/protocol/session_specifics.proto index 5b00b358..bfed4aa 100644 --- a/chrome/browser/sync/protocol/session_specifics.proto +++ b/chrome/browser/sync/protocol/session_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for sessions. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/sync.proto b/chrome/browser/sync/protocol/sync.proto index 1ada951..1b778f3 100644 --- a/chrome/browser/sync/protocol/sync.proto +++ b/chrome/browser/sync/protocol/sync.proto @@ -4,6 +4,9 @@ // // Sync protocol for communication between sync client and server. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/theme_specifics.proto b/chrome/browser/sync/protocol/theme_specifics.proto index 5439bc4..eb864ff 100644 --- a/chrome/browser/sync/protocol/theme_specifics.proto +++ b/chrome/browser/sync/protocol/theme_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for themes. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/browser/sync/protocol/typed_url_specifics.proto b/chrome/browser/sync/protocol/typed_url_specifics.proto index 7dd4041..011ae4e 100644 --- a/chrome/browser/sync/protocol/typed_url_specifics.proto +++ b/chrome/browser/sync/protocol/typed_url_specifics.proto @@ -4,6 +4,9 @@ // // Sync protocol datatype extension for typed urls. +// Update proto_value_conversions{.h,.cc,_unittest.cc} if you change +// any fields in this file. + syntax = "proto2"; option optimize_for = LITE_RUNTIME; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index f1da091e..c5fdad4 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -964,6 +964,10 @@ 'browser/sync/js_event_handler_list.h', 'browser/sync/js_event_router.h', 'browser/sync/js_frontend.h', + 'browser/sync/protocol/proto_enum_conversions.cc', + 'browser/sync/protocol/proto_enum_conversions.h', + 'browser/sync/protocol/proto_value_conversions.cc', + 'browser/sync/protocol/proto_value_conversions.h', 'browser/sync/protocol/service_constants.h', 'browser/sync/sessions/ordered_commit_set.cc', 'browser/sync/sessions/ordered_commit_set.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 38ce812..2e34646 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -2751,6 +2751,8 @@ 'browser/sync/notifier/registration_manager_unittest.cc', 'browser/sync/notifier/server_notifier_thread_unittest.cc', 'browser/sync/profile_sync_factory_mock.h', + 'browser/sync/protocol/proto_enum_conversions_unittest.cc', + 'browser/sync/protocol/proto_value_conversions_unittest.cc', 'browser/sync/sessions/ordered_commit_set_unittest.cc', 'browser/sync/sessions/status_controller_unittest.cc', 'browser/sync/sessions/sync_session_unittest.cc', |