diff options
-rw-r--r-- | chrome/browser/sync/glue/synced_device_tracker.cc | 55 | ||||
-rw-r--r-- | chrome/browser/sync/glue/synced_device_tracker.h | 10 | ||||
-rw-r--r-- | chrome/browser/sync/glue/synced_device_tracker_unittest.cc | 47 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 58 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.h | 12 | ||||
-rw-r--r-- | chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc | 31 | ||||
-rw-r--r-- | sync/internal_api/DEPS | 1 | ||||
-rw-r--r-- | sync/internal_api/public/util/sync_db_util.h | 30 | ||||
-rw-r--r-- | sync/internal_api/sync_db_util.cc | 38 | ||||
-rw-r--r-- | sync/protocol/DEPS | 1 | ||||
-rw-r--r-- | sync/protocol/device_info_specifics.proto | 4 | ||||
-rw-r--r-- | sync/protocol/proto_value_conversions.cc | 10 | ||||
-rw-r--r-- | sync/sync_internal_api.gypi | 2 |
13 files changed, 267 insertions, 32 deletions
diff --git a/chrome/browser/sync/glue/synced_device_tracker.cc b/chrome/browser/sync/glue/synced_device_tracker.cc index bf7fa92..e77463e 100644 --- a/chrome/browser/sync/glue/synced_device_tracker.cc +++ b/chrome/browser/sync/glue/synced_device_tracker.cc @@ -13,6 +13,7 @@ #include "sync/internal_api/public/user_share.h" #include "sync/internal_api/public/write_node.h" #include "sync/internal_api/public/write_transaction.h" +#include "sync/util/time.h" namespace browser_sync { @@ -157,25 +158,28 @@ void SyncedDeviceTracker::InitLocalDeviceInfoContinuation( } void SyncedDeviceTracker::WriteLocalDeviceInfo(const DeviceInfo& info) { - sync_pb::DeviceInfoSpecifics specifics; DCHECK_EQ(cache_guid_, info.guid()); - specifics.set_cache_guid(cache_guid_); - specifics.set_client_name(info.client_name()); - specifics.set_chrome_version(info.chrome_version()); - specifics.set_sync_user_agent(info.sync_user_agent()); - specifics.set_device_type(info.device_type()); - - WriteDeviceInfo(specifics, local_device_info_tag_); + WriteDeviceInfo(info, local_device_info_tag_); } -void SyncedDeviceTracker::WriteDeviceInfo( - const sync_pb::DeviceInfoSpecifics& specifics, - const std::string& tag) { +void SyncedDeviceTracker::WriteDeviceInfo(const DeviceInfo& info, + const std::string& tag) { syncer::WriteTransaction trans(FROM_HERE, user_share_); syncer::WriteNode node(&trans); + sync_pb::DeviceInfoSpecifics specifics; + specifics.set_cache_guid(info.guid()); + specifics.set_client_name(info.client_name()); + specifics.set_chrome_version(info.chrome_version()); + specifics.set_sync_user_agent(info.sync_user_agent()); + specifics.set_device_type(info.device_type()); + if (node.InitByClientTagLookup(syncer::DEVICE_INFO, tag) == syncer::BaseNode::INIT_OK) { + const sync_pb::DeviceInfoSpecifics& sync_specifics = + node.GetDeviceInfoSpecifics(); + if (sync_specifics.has_backup_timestamp()) + specifics.set_backup_timestamp(sync_specifics.backup_timestamp()); node.SetDeviceInfoSpecifics(specifics); node.SetTitle(specifics.client_name()); } else { @@ -195,4 +199,33 @@ void SyncedDeviceTracker::WriteDeviceInfo( } } +void SyncedDeviceTracker::UpdateLocalDeviceBackupTime(base::Time backup_time) { + syncer::WriteTransaction trans(FROM_HERE, user_share_); + syncer::WriteNode node(&trans); + + if (node.InitByClientTagLookup(syncer::DEVICE_INFO, local_device_info_tag_) + == syncer::BaseNode::INIT_OK) { + sync_pb::DeviceInfoSpecifics specifics = node.GetDeviceInfoSpecifics(); + int64 new_backup_timestamp = syncer::TimeToProtoTime(backup_time); + if (!specifics.has_backup_timestamp() || + specifics.backup_timestamp() != new_backup_timestamp) { + specifics.set_backup_timestamp(new_backup_timestamp); + node.SetDeviceInfoSpecifics(specifics); + } + } +} + +base::Time SyncedDeviceTracker::GetLocalDeviceBackupTime() const { + syncer::ReadTransaction trans(FROM_HERE, user_share_); + syncer::ReadNode node(&trans); + if (node.InitByClientTagLookup(syncer::DEVICE_INFO, local_device_info_tag_) + == syncer::BaseNode::INIT_OK && + node.GetDeviceInfoSpecifics().has_backup_timestamp()) { + return syncer::ProtoTimeToTime( + node.GetDeviceInfoSpecifics().backup_timestamp()); + } else { + return base::Time(); + } +} + } // namespace browser_sync diff --git a/chrome/browser/sync/glue/synced_device_tracker.h b/chrome/browser/sync/glue/synced_device_tracker.h index 3f0844a..1bc2d66 100644 --- a/chrome/browser/sync/glue/synced_device_tracker.h +++ b/chrome/browser/sync/glue/synced_device_tracker.h @@ -61,6 +61,13 @@ class SyncedDeviceTracker : public ChangeProcessor { void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + // Update |backup_timestamp| in local device info specifics to |backup_time| + // if different. + void UpdateLocalDeviceBackupTime(base::Time backup_time); + + // Return time derived from |backup_timestamp| in local device info specifics. + base::Time GetLocalDeviceBackupTime() const; + private: friend class SyncedDeviceTrackerTest; @@ -72,8 +79,7 @@ class SyncedDeviceTracker : public ChangeProcessor { // Helper to write arbitrary device info. Useful for writing local device // info and also used by test cases to write arbitrary device infos. - void WriteDeviceInfo(const sync_pb::DeviceInfoSpecifics& specifics, - const std::string& tag); + void WriteDeviceInfo(const DeviceInfo& info, const std::string& tag); syncer::UserShare* user_share_; const std::string cache_guid_; diff --git a/chrome/browser/sync/glue/synced_device_tracker_unittest.cc b/chrome/browser/sync/glue/synced_device_tracker_unittest.cc index 4596b5a1..267d047 100644 --- a/chrome/browser/sync/glue/synced_device_tracker_unittest.cc +++ b/chrome/browser/sync/glue/synced_device_tracker_unittest.cc @@ -20,20 +20,6 @@ namespace browser_sync { -namespace { - -void ConvertDeviceInfoSpecifics( - const DeviceInfo& device_info, - sync_pb::DeviceInfoSpecifics* specifics) { - specifics->set_cache_guid(device_info.guid()); - specifics->set_client_name(device_info.client_name()); - specifics->set_chrome_version(device_info.chrome_version()); - specifics->set_sync_user_agent(device_info.sync_user_agent()); - specifics->set_device_type(device_info.device_type()); -} - -} // namespace - class SyncedDeviceTrackerTest : public ::testing::Test { protected: SyncedDeviceTrackerTest() : transaction_count_baseline_(0) { } @@ -69,9 +55,7 @@ class SyncedDeviceTrackerTest : public ::testing::Test { } void WriteDeviceInfo(const DeviceInfo& device_info) { - sync_pb::DeviceInfoSpecifics specifics; - ConvertDeviceInfoSpecifics(device_info, &specifics); - synced_device_tracker_->WriteDeviceInfo(specifics, device_info.guid()); + synced_device_tracker_->WriteDeviceInfo(device_info, device_info.guid()); } void ResetObservedChangesCounter() { @@ -208,6 +192,35 @@ TEST_F(SyncedDeviceTrackerTest, GetAllDeviceInfo) { EXPECT_TRUE(device_info[1]->Equals(device_info2)); } +TEST_F(SyncedDeviceTrackerTest, DeviceBackupTime) { + DeviceInfo device_info( + user_share()->directory->cache_guid(), + "John’s Device", "XYZ v1", "XYZ SyncAgent v1", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX); + const base::Time test_backup_time = + base::Time::UnixEpoch() + base::TimeDelta::FromDays(10000); + + WriteLocalDeviceInfo(device_info); + synced_device_tracker_->UpdateLocalDeviceBackupTime(test_backup_time); + + // Verify read of device info and backup time. + EXPECT_EQ(test_backup_time, + synced_device_tracker_->GetLocalDeviceBackupTime()); + scoped_ptr<DeviceInfo> device_info_out( + synced_device_tracker_->ReadLocalDeviceInfo()); + ASSERT_TRUE(device_info_out); + EXPECT_TRUE(device_info.Equals(*device_info_out.get())); + + // Verify backup time is not lost after updating device info. + DeviceInfo device_info2( + user_share()->directory->cache_guid(), + "def Device", "XYZ v2", "XYZ SyncAgent v2", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX); + WriteLocalDeviceInfo(device_info2); + EXPECT_EQ(test_backup_time, + synced_device_tracker_->GetLocalDeviceBackupTime()); +} + } // namespace } // namespace browser_sync diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index cd24db0e..9102c4a 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -76,6 +76,7 @@ #include "components/sync_driver/pref_names.h" #include "components/sync_driver/system_encryptor.h" #include "components/sync_driver/user_selectable_sync_type.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" @@ -90,6 +91,7 @@ #include "sync/internal_api/public/sync_context_proxy.h" #include "sync/internal_api/public/sync_encryption_handler.h" #include "sync/internal_api/public/util/experiments.h" +#include "sync/internal_api/public/util/sync_db_util.h" #include "sync/internal_api/public/util/sync_string_conversions.h" #include "sync/js/js_event_details.h" #include "sync/util/cryptographer.h" @@ -658,6 +660,8 @@ void ProfileSyncService::StartUpSlowBackendComponents( if (backend_mode_ == ROLLBACK) ClearBrowsingDataSinceFirstSync(); + else if (backend_mode_ == SYNC) + CheckSyncBackupIfNeeded(); base::FilePath sync_folder = backend_mode_ == SYNC ? base::FilePath(kSyncDataFolderName) : @@ -1022,6 +1026,13 @@ void ProfileSyncService::PostBackendInitialization() { // Never get here for backup / restore. DCHECK_EQ(backend_mode_, SYNC); + if (last_backup_time_) { + browser_sync::SyncedDeviceTracker* device_tracker = + backend_->GetSyncedDeviceTracker(); + if (device_tracker) + device_tracker->UpdateLocalDeviceBackupTime(*last_backup_time_); + } + if (protocol_event_observers_.might_have_observers()) { backend_->RequestBufferedProtocolEventsAndEnableForwarding(); } @@ -2597,3 +2608,50 @@ void ProfileSyncService::StartStopBackupForTesting() { else backup_rollback_controller_.Start(base::TimeDelta()); } + +void ProfileSyncService::CheckSyncBackupIfNeeded() { + DCHECK_EQ(backend_mode_, SYNC); + +#if defined(ENABLE_PRE_SYNC_BACKUP) + // Check backup once a day. + if (!last_backup_time_ && + (last_synced_time_.is_null() || + base::Time::Now() - last_synced_time_ >= + base::TimeDelta::FromDays(1))) { + // If sync thread is set, need to serialize check on sync thread after + // closing backup DB. + if (sync_thread_) { + sync_thread_->message_loop_proxy()->PostTask( + FROM_HERE, + base::Bind(syncer::CheckSyncDbLastModifiedTime, + profile_->GetPath().Append(kSyncBackupDataFolderName), + base::MessageLoopProxy::current(), + base::Bind(&ProfileSyncService::CheckSyncBackupCallback, + weak_factory_.GetWeakPtr()))); + } else { + content::BrowserThread::PostTask( + content::BrowserThread::FILE, FROM_HERE, + base::Bind(syncer::CheckSyncDbLastModifiedTime, + profile_->GetPath().Append(kSyncBackupDataFolderName), + base::MessageLoopProxy::current(), + base::Bind(&ProfileSyncService::CheckSyncBackupCallback, + weak_factory_.GetWeakPtr()))); + } + } +#endif +} + +void ProfileSyncService::CheckSyncBackupCallback(base::Time backup_time) { + last_backup_time_.reset(new base::Time(backup_time)); + + if (HasSyncingBackend() && backend_initialized_) { + browser_sync::SyncedDeviceTracker* device_tracker = + backend_->GetSyncedDeviceTracker(); + if (device_tracker) + device_tracker->UpdateLocalDeviceBackupTime(*last_backup_time_); + } +} + +base::Time ProfileSyncService::GetDeviceBackupTimeForTesting() const { + return backend_->GetSyncedDeviceTracker()->GetLocalDeviceBackupTime(); +} diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index 5b695fb..ccb4606 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -782,6 +782,8 @@ class ProfileSyncService : public ProfileSyncServiceBase, void StartStopBackupForTesting(); + base::Time GetDeviceBackupTimeForTesting() const; + protected: // Helper to configure the priority data types. void ConfigurePriorityDataTypes(); @@ -957,6 +959,12 @@ class ProfileSyncService : public ProfileSyncServiceBase, // Clear browsing data since first sync during rollback. void ClearBrowsingDataSinceFirstSync(); + // Post background task to check sync backup DB state if needed. + void CheckSyncBackupIfNeeded(); + + // Callback to receive backup DB check result. + void CheckSyncBackupCallback(base::Time backup_time); + // Factory used to create various dependent objects. scoped_ptr<ProfileSyncComponentsFactory> factory_; @@ -1124,6 +1132,10 @@ class ProfileSyncService : public ProfileSyncServiceBase, base::Callback<void(Profile*, base::Time, base::Time)> clear_browsing_data_; + // Last time when pre-sync data was saved. NULL pointer means backup data + // state is unknown. If time value is null, backup data doesn't exist. + scoped_ptr<base::Time> last_backup_time_; + DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); }; diff --git a/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc b/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc index 3321669..6de9eb2 100644 --- a/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc +++ b/chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc @@ -5,6 +5,7 @@ #include "base/command_line.h" #include "base/message_loop/message_loop.h" #include "base/prefs/pref_service.h" +#include "base/run_loop.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/test/integration/bookmarks_helper.h" @@ -14,7 +15,9 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "sync/internal_api/public/util/sync_db_util.h" #include "sync/test/fake_server/fake_server_verifier.h" +#include "sync/util/time.h" using bookmarks_helper::AddFolder; using bookmarks_helper::AddURL; @@ -45,7 +48,26 @@ class SingleClientBackupRollbackTest : public SyncTest { switches::kSyncEnableRollback); } + base::Time GetBackupDbLastModified() { + base::RunLoop run_loop; + + base::Time backup_time; + syncer::CheckSyncDbLastModifiedTime( + GetProfile(0)->GetPath().Append(FILE_PATH_LITERAL("Sync Data Backup")), + base::MessageLoopProxy::current(), + base::Bind(&SingleClientBackupRollbackTest::CheckDbCallback, + base::Unretained(this), &backup_time)); + base::MessageLoopProxy::current()->PostTask( + FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + return backup_time; + } + private: + void CheckDbCallback(base::Time* time_out, base::Time time_in) { + *time_out = syncer::ProtoTimeToTime(syncer::TimeToProtoTime(time_in)); + } + DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest); }; @@ -188,16 +210,21 @@ IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest, // Setup sync, wait for its completion, and make sure changes were synced. ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; - ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); + ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0))); ASSERT_TRUE(ModelMatchesVerifier(0)); // Made bookmark changes while sync is on. Move(0, tier1_a->GetChild(0), tier1_b, 1); Remove(0, tier1_b, 0); ASSERT_TRUE(AddFolder(0, tier1_b, 1, "tier2_c")); - ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0)))); + ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService(0))); ASSERT_TRUE(ModelMatchesVerifier(0)); + // Verify backup time is set on device info. + base::Time backup_time = GetBackupDbLastModified(); + ASSERT_FALSE(backup_time.is_null()); + ASSERT_EQ(backup_time, GetSyncService(0)->GetDeviceBackupTimeForTesting()); + // Let server to return rollback command on next sync request. GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK); diff --git a/sync/internal_api/DEPS b/sync/internal_api/DEPS index 13e6b8a..42ab18e 100644 --- a/sync/internal_api/DEPS +++ b/sync/internal_api/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+net/http", "+net/test", "+net/url_request", + "+sql", "+sync/base", "+sync/engine", "+sync/js", diff --git a/sync/internal_api/public/util/sync_db_util.h b/sync/internal_api/public/util/sync_db_util.h new file mode 100644 index 0000000..3784a10 --- /dev/null +++ b/sync/internal_api/public/util/sync_db_util.h @@ -0,0 +1,30 @@ +// Copyright 2014 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 SYNC_INTERNAL_API_PUBLIC_UTIL_SYNC_DB_UTIL_H_ +#define SYNC_INTERNAL_API_PUBLIC_UTIL_SYNC_DB_UTIL_H_ + +#include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/time/time.h" +#include "sync/base/sync_export.h" + +namespace base { +class FilePath; +class SingleThreadTaskRunner; +} // namespace base + +namespace syncer { + +// Check integrity of sync DB under |sync_dir|. Invoke |callback| with last +// modified time if integrity check passes, with NULL time otherwise. This +// is called on either sync thread or IO thread. +SYNC_EXPORT void CheckSyncDbLastModifiedTime( + const base::FilePath& sync_dir, + scoped_refptr<base::SingleThreadTaskRunner> callback_runner, + base::Callback<void(base::Time)> callback); + +} // namesapce syncer + +#endif // SYNC_INTERNAL_API_PUBLIC_UTIL_SYNC_DB_UTIL_H_ diff --git a/sync/internal_api/sync_db_util.cc b/sync/internal_api/sync_db_util.cc new file mode 100644 index 0000000..c12889d --- /dev/null +++ b/sync/internal_api/sync_db_util.cc @@ -0,0 +1,38 @@ +// Copyright 2014 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. + +#include "sync/internal_api/public/util/sync_db_util.h" + +#include "base/files/file_path.h" +#include "base/single_thread_task_runner.h" +#include "sql/connection.h" +#include "sync/syncable/directory.h" + +namespace syncer { + +void CheckSyncDbLastModifiedTime( + const base::FilePath& sync_dir, + scoped_refptr<base::SingleThreadTaskRunner> callback_runner, + base::Callback<void(base::Time)> callback) { + const base::FilePath sync_db = + sync_dir.Append(syncable::Directory::kSyncDatabaseFilename); + + base::File f(sync_db, base::File::FLAG_OPEN | base::File::FLAG_READ); + base::File::Info info; + if (!f.IsValid() || !f.GetInfo(&info)) { + callback_runner->PostTask(FROM_HERE, base::Bind(callback, base::Time())); + return; + } + f.Close(); + + sql::Connection db; + if (!db.Open(sync_db) || !db.QuickIntegrityCheck()) { + callback_runner->PostTask(FROM_HERE, base::Bind(callback, base::Time())); + } else { + callback_runner->PostTask(FROM_HERE, + base::Bind(callback, info.last_modified)); + } +} + +} // namespace syncer diff --git a/sync/protocol/DEPS b/sync/protocol/DEPS index f8f9de5..d623db8 100644 --- a/sync/protocol/DEPS +++ b/sync/protocol/DEPS @@ -1,4 +1,5 @@ include_rules = [ "+sync/base", "+sync/internal_api/public/base", + "+sync/util", ] diff --git a/sync/protocol/device_info_specifics.proto b/sync/protocol/device_info_specifics.proto index 67eb469..f87b361 100644 --- a/sync/protocol/device_info_specifics.proto +++ b/sync/protocol/device_info_specifics.proto @@ -34,4 +34,8 @@ message DeviceInfoSpecifics { // The Chrome instance's version. Updated (if necessary) on every startup. optional string chrome_version = 5; + + // Last time when pre-sync data on the device was saved. The device can be + // restored to state back to this time. In millisecond since UNIX epoch. + optional int64 backup_timestamp = 6; } diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc index 8e58af4..2716210 100644 --- a/sync/protocol/proto_value_conversions.cc +++ b/sync/protocol/proto_value_conversions.cc @@ -10,8 +10,10 @@ #include "base/base64.h" #include "base/basictypes.h" +#include "base/i18n/time_formatting.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" +#include "base/time/time.h" #include "base/values.h" #include "sync/internal_api/public/base/unique_position.h" #include "sync/protocol/app_list_specifics.pb.h" @@ -41,6 +43,7 @@ #include "sync/protocol/theme_specifics.pb.h" #include "sync/protocol/typed_url_specifics.pb.h" #include "sync/protocol/unique_position.pb.h" +#include "sync/util/time.h" namespace syncer { @@ -82,6 +85,11 @@ base::ListValue* MakeRepeatedValue(const F& fields, V* (*converter_fn)(T)) { return list; } +base::StringValue* MakeTimestampValue(int64 tm) { + return new base::StringValue( + base::TimeFormatShortDateAndTime(syncer::ProtoTimeToTime(tm))); +} + } // namespace // Helper macros to reduce the amount of boilerplate. @@ -102,6 +110,7 @@ base::ListValue* MakeRepeatedValue(const F& fields, V* (*converter_fn)(T)) { #define SET_INT64(field) SET(field, MakeInt64Value) #define SET_INT64_REP(field) SET_REP(field, MakeInt64Value) #define SET_STR(field) SET(field, new base::StringValue) +#define SET_TIME_STR(field) SET(field, MakeTimestampValue) #define SET_STR_REP(field) \ value->Set(#field, \ MakeRepeatedValue<const std::string&, \ @@ -489,6 +498,7 @@ base::DictionaryValue* DeviceInfoSpecificsToValue( SET_ENUM(device_type, GetDeviceTypeString); SET_STR(sync_user_agent); SET_STR(chrome_version); + SET_TIME_STR(backup_timestamp); return value; } diff --git a/sync/sync_internal_api.gypi b/sync/sync_internal_api.gypi index 1ff913f..7d92f68 100644 --- a/sync/sync_internal_api.gypi +++ b/sync/sync_internal_api.gypi @@ -135,6 +135,7 @@ 'internal_api/public/util/report_unrecoverable_error_function.h', 'internal_api/public/util/sync_string_conversions.cc', 'internal_api/public/util/sync_string_conversions.h', + 'internal_api/public/util/sync_db_util.h', 'internal_api/public/util/syncer_error.cc', 'internal_api/public/util/syncer_error.h', 'internal_api/public/util/unrecoverable_error_handler.h', @@ -152,6 +153,7 @@ 'internal_api/sync_context_proxy.cc', 'internal_api/sync_context_proxy_impl.cc', 'internal_api/sync_context_proxy_impl.h', + 'internal_api/sync_db_util.cc', 'internal_api/sync_encryption_handler_impl.cc', 'internal_api/sync_encryption_handler_impl.h', 'internal_api/sync_manager_factory.cc', |