summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/sync/glue/synced_device_tracker.cc55
-rw-r--r--chrome/browser/sync/glue/synced_device_tracker.h10
-rw-r--r--chrome/browser/sync/glue/synced_device_tracker_unittest.cc47
-rw-r--r--chrome/browser/sync/profile_sync_service.cc58
-rw-r--r--chrome/browser/sync/profile_sync_service.h12
-rw-r--r--chrome/browser/sync/test/integration/single_client_backup_rollback_test.cc31
6 files changed, 181 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);