Skip to content

Commit

Permalink
Merge pull request #1135 from brave/sync-delete-reset
Browse files Browse the repository at this point in the history
Prevent duplicate nodes from reconnect and refine reset to make sure deleted record is sent
  • Loading branch information
darkdh committed Dec 19, 2018
1 parent a323a0d commit 27f2159
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 19 deletions.
9 changes: 9 additions & 0 deletions components/brave_sync/brave_sync_prefs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace prefs {

const char kSyncDeviceId[] = "brave_sync.device_id";
const char kSyncSeed[] = "brave_sync.seed";
const char kSyncPrevSeed[] = "brave_sync.previous_seed";
const char kSyncDeviceName[] = "brave_sync.device_name";
const char kSyncBookmarksBaseOrder[] = "brave_sync.bookmarks_base_order";
const char kSyncEnabled[] = "brave_sync.enabled";
Expand All @@ -36,6 +37,14 @@ void Prefs::SetSeed(const std::string& seed) {
pref_service_->SetString(kSyncSeed, seed);
}

std::string Prefs::GetPrevSeed() const {
return pref_service_->GetString(kSyncPrevSeed);
}

void Prefs::SetPrevSeed(const std::string& seed) {
pref_service_->SetString(kSyncPrevSeed, seed);
}

std::string Prefs::GetThisDeviceId() const {
return pref_service_->GetString(kSyncDeviceId);
}
Expand Down
4 changes: 4 additions & 0 deletions components/brave_sync/brave_sync_prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ extern const char kSyncDeviceId[];
// String of 32 comma separated bytes
// like "145,58,125,111,85,164,236,38,204,67,40,31,182,114,14,152,242,..."
extern const char kSyncSeed[];
// For storing previous seed after reset. It won't be cleared by Clear()
extern const char kSyncPrevSeed[];
// String of current device namefor sync
extern const char kSyncDeviceName[];
// The initial bookmarks order, in a format of
Expand Down Expand Up @@ -57,6 +59,8 @@ class Prefs {

std::string GetSeed() const;
void SetSeed(const std::string& seed);
std::string GetPrevSeed() const;
void SetPrevSeed(const std::string& seed);
std::string GetThisDeviceId() const;
void SetThisDeviceId(const std::string& device_id);
std::string GetThisDeviceName() const;
Expand Down
1 change: 1 addition & 0 deletions components/brave_sync/brave_sync_service_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void BraveSyncServiceFactory::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterStringPref(prefs::kSyncDeviceId, std::string());
registry->RegisterStringPref(prefs::kSyncSeed, std::string());
registry->RegisterStringPref(prefs::kSyncPrevSeed, std::string());
registry->RegisterStringPref(prefs::kSyncDeviceName, std::string());
registry->RegisterStringPref(prefs::kSyncBookmarksBaseOrder, std::string());

Expand Down
36 changes: 26 additions & 10 deletions components/brave_sync/brave_sync_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,16 +239,9 @@ void BraveSyncServiceImpl::OnResetSync() {

const std::string device_id = sync_prefs_->GetThisDeviceId();

bookmark_change_processor_->Reset();

// We have to send delete record and wait for library deleted response then we
// can reset it by ResetInternal()
OnDeleteDevice(device_id);

sync_prefs_->Clear();

sync_configured_ = false;
sync_initialized_ = false;

sync_prefs_->SetSyncEnabled(false);
}

void BraveSyncServiceImpl::GetSettingsAndDevices(
Expand Down Expand Up @@ -372,8 +365,16 @@ void BraveSyncServiceImpl::OnSaveInitData(const Uint8Array& seed,
std::string seed_str = StrFromUint8Array(seed);
std::string device_id_str = StrFromUint8Array(device_id);

std::string prev_seed_str = sync_prefs_->GetPrevSeed();

sync_words_.clear();
DCHECK(!seed_str.empty());
if (prev_seed_str == seed_str) { // reconnecitng to previous sync chain
sync_prefs_->SetPrevSeed(std::string());
} else if (!prev_seed_str.empty()) { // connect/create to new sync chain
bookmark_change_processor_->Reset(true);
sync_prefs_->SetPrevSeed(std::string());
} // else {} no previous sync chain
sync_prefs_->SetSeed(seed_str);
sync_prefs_->SetThisDeviceId(device_id_str);

Expand Down Expand Up @@ -494,7 +495,9 @@ void BraveSyncServiceImpl::OnResolvedPreferences(const RecordsList& records) {

sync_prefs_->SetSyncDevices(*sync_devices);

if (this_device_deleted || contains_only_one_device)
if (this_device_deleted)
ResetSyncInternal();
if (contains_only_one_device)
OnResetSync();
}

Expand Down Expand Up @@ -663,4 +666,17 @@ void BraveSyncServiceImpl::NotifyHaveSyncWords(
observer.OnHaveSyncWords(this, sync_words);
}

void BraveSyncServiceImpl::ResetSyncInternal() {
bookmark_change_processor_->Reset(false);

sync_prefs_->SetPrevSeed(sync_prefs_->GetSeed());

sync_prefs_->Clear();

sync_configured_ = false;
sync_initialized_ = false;

sync_prefs_->SetSyncEnabled(false);
}

} // namespace brave_sync
4 changes: 4 additions & 0 deletions components/brave_sync/brave_sync_service_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ class BraveSyncServiceImpl
void NotifySyncStateChanged();
void NotifyHaveSyncWords(const std::string& sync_words);

void ResetSyncInternal();

std::unique_ptr<BraveSyncClient> sync_client_;

// True when is in active sync chain
Expand All @@ -183,6 +185,8 @@ class BraveSyncServiceImpl
// while being initializing
bool initializing_ = false;

bool reseting_ = false;

std::string sync_words_;

std::unique_ptr<brave_sync::Settings> settings_;
Expand Down
24 changes: 21 additions & 3 deletions components/brave_sync/brave_sync_service_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -371,9 +371,11 @@ TEST_F(BraveSyncServiceTest, GetSeed) {
// Service gets seed from client via BraveSyncServiceImpl::OnSaveInitData
const auto binary_seed = Uint8Array(16, 77);

EXPECT_TRUE(sync_service()->sync_prefs_->GetPrevSeed().empty());
sync_service()->OnSaveInitData(binary_seed, {0});
std::string expected_seed = StrFromUint8Array(binary_seed);
EXPECT_EQ(sync_service()->GetSeed(), expected_seed);
EXPECT_TRUE(sync_service()->sync_prefs_->GetPrevSeed().empty());
}

bool DevicesContains(SyncDevices* devices, const std::string& id,
Expand Down Expand Up @@ -415,6 +417,7 @@ TEST_F(BraveSyncServiceTest, OnDeleteDevice) {
EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1);
sync_service()->OnResolvedPreferences(records);

sync_service()->sync_prefs_->SetThisDeviceId("1");
auto devices = sync_service()->sync_prefs_->GetSyncDevices();

EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1"));
Expand All @@ -440,6 +443,7 @@ TEST_F(BraveSyncServiceTest, OnDeleteDevice) {
}

TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) {
sync_service()->sync_prefs_->SetThisDeviceId("1");
RecordsList records;
records.push_back(SimpleDeviceRecord(
jslib::SyncRecord::Action::A_CREATE,
Expand All @@ -456,14 +460,21 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) {
EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2"));

using brave_sync::jslib::SyncRecord;
EXPECT_CALL(*sync_client(), SendSyncRecords("PREFERENCES",
ContainsDeviceRecord(SyncRecord::Action::A_DELETE, "device2"))).Times(1);
// device 2 => device 1
EXPECT_CALL(*sync_client(), SendSyncRecords).Times(2);
sync_service()->OnDeleteDevice("2");

RecordsList resolved_records;
auto resolved_record = SyncRecord::Clone(*records.at(1));
resolved_record->action = jslib::SyncRecord::Action::A_DELETE;
resolved_records.push_back(std::move(resolved_record));
EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1);
sync_service()->OnResolvedPreferences(resolved_records);

resolved_records.clear();
resolved_record = SyncRecord::Clone(*records.at(0));
resolved_record->action = jslib::SyncRecord::Action::A_DELETE;
resolved_records.push_back(std::move(resolved_record));
EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(3);
sync_service()->OnResolvedPreferences(resolved_records);

Expand All @@ -475,6 +486,7 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) {
}

TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) {
sync_service()->sync_prefs_->SetThisDeviceId("1");
RecordsList records;
records.push_back(SimpleDeviceRecord(
jslib::SyncRecord::Action::A_CREATE,
Expand Down Expand Up @@ -510,11 +522,12 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) {
}

TEST_F(BraveSyncServiceTest, OnResetSync) {
EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(AtLeast(2));
EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(AtLeast(1));
EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(AtLeast(3));
sync_service()->OnSetupSyncNewToSync("this_device");
EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(
brave_sync::prefs::kSyncEnabled));
sync_service()->sync_prefs_->SetThisDeviceId("0");

RecordsList records;
records.push_back(SimpleDeviceRecord(
Expand All @@ -532,6 +545,11 @@ TEST_F(BraveSyncServiceTest, OnResetSync) {
EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1"));

sync_service()->OnResetSync();
RecordsList resolved_records;
auto resolved_record = jslib::SyncRecord::Clone(*records.at(0));
resolved_record->action = jslib::SyncRecord::Action::A_DELETE;
resolved_records.push_back(std::move(resolved_record));
sync_service()->OnResolvedPreferences(resolved_records);

auto devices_final = sync_service()->sync_prefs_->GetSyncDevices();
EXPECT_FALSE(DevicesContains(devices_final.get(), "0", "this_device"));
Expand Down
7 changes: 5 additions & 2 deletions components/brave_sync/client/bookmark_change_processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,12 @@ void BookmarkChangeProcessor::BookmarkNodeChildrenReordered(
// this should be safe to ignore as it's only called for managed bookmarks
}

void BookmarkChangeProcessor::Reset() {
void BookmarkChangeProcessor::Reset(bool clear_meta_info) {
ui::TreeNodeIterator<const bookmarks::BookmarkNode>
iterator(bookmark_model_->root_node());
bookmark_model_->BeginExtensiveChanges();

{
if (clear_meta_info) {
ScopedPauseObserver pause(this);
while (iterator.has_next()) {
const bookmarks::BookmarkNode* node = iterator.Next();
Expand All @@ -425,6 +425,9 @@ void BookmarkChangeProcessor::Reset() {
auto* deleted_node = GetDeletedNodeRoot();
CHECK(deleted_node);
deleted_node->DeleteAll();
auto* pending_node = GetPendingNodeRoot();
CHECK(pending_node);
pending_node->DeleteAll();
bookmark_model_->EndExtensiveChanges();
}

Expand Down
2 changes: 1 addition & 1 deletion components/brave_sync/client/bookmark_change_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class BookmarkChangeProcessor : public ChangeProcessor,
// ChangeProcessor implementation
void Start() override;
void Stop() override;
void Reset() override;
void Reset(bool clear_meta_info) override;
void ApplyChangesFromSyncModel(const RecordsList &records) override;
void GetAllSyncData(
const std::vector<std::unique_ptr<jslib::SyncRecord>>& records,
Expand Down
54 changes: 52 additions & 2 deletions components/brave_sync/client/bookmark_change_processor_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ void BraveBookmarkChangeProcessorTest::AddSimpleHierarchy(
GURL("https://c.com/"));
}

TEST_F(BraveBookmarkChangeProcessorTest, Reset) {
TEST_F(BraveBookmarkChangeProcessorTest, ResetClearMeta) {
// Reset does clear of the metainfo, but
// to fillup the metainfo now need to send it to sync
change_processor()->Start();
Expand All @@ -260,14 +260,64 @@ TEST_F(BraveBookmarkChangeProcessorTest, Reset) {
EXPECT_TRUE(HasAnySyncMetaInfo(node_b));
EXPECT_TRUE(HasAnySyncMetaInfo(node_c));

change_processor()->Reset();
model()->AddURL(GetDeletedNodeRoot(), 0,
base::ASCIIToUTF16("A.com - title"),
GURL("https://a.com/"));
model()->AddURL(GetPendingNodeRoot(), 0,
base::ASCIIToUTF16("A.com - title"),
GURL("https://a.com/"));
EXPECT_FALSE(GetDeletedNodeRoot()->empty());
EXPECT_FALSE(GetPendingNodeRoot()->empty());

change_processor()->Reset(true);

EXPECT_FALSE(HasAnySyncMetaInfo(folder1));
EXPECT_FALSE(HasAnySyncMetaInfo(node_a));
EXPECT_FALSE(HasAnySyncMetaInfo(node_b));
EXPECT_FALSE(HasAnySyncMetaInfo(node_c));
EXPECT_TRUE(GetDeletedNodeRoot()->empty());
EXPECT_TRUE(GetPendingNodeRoot()->empty());
}

TEST_F(BraveBookmarkChangeProcessorTest, ResetPreserveMeta) {
// Reset does clear of the metainfo, but
// to fillup the metainfo now need to send it to sync
change_processor()->Start();

const BookmarkNode* folder1;
const BookmarkNode* node_a;
const BookmarkNode* node_b;
const BookmarkNode* node_c;
AddSimpleHierarchy(&folder1, &node_a, &node_b, &node_c);

EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(1);
change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10));

EXPECT_TRUE(HasAnySyncMetaInfo(folder1));
EXPECT_TRUE(HasAnySyncMetaInfo(node_a));
EXPECT_TRUE(HasAnySyncMetaInfo(node_b));
EXPECT_TRUE(HasAnySyncMetaInfo(node_c));

model()->AddURL(GetDeletedNodeRoot(), 0,
base::ASCIIToUTF16("A.com - title"),
GURL("https://a.com/"));
model()->AddURL(GetPendingNodeRoot(), 0,
base::ASCIIToUTF16("A.com - title"),
GURL("https://a.com/"));
EXPECT_FALSE(GetDeletedNodeRoot()->empty());
EXPECT_FALSE(GetPendingNodeRoot()->empty());

change_processor()->Reset(false);

EXPECT_TRUE(HasAnySyncMetaInfo(folder1));
EXPECT_TRUE(HasAnySyncMetaInfo(node_a));
EXPECT_TRUE(HasAnySyncMetaInfo(node_b));
EXPECT_TRUE(HasAnySyncMetaInfo(node_c));
EXPECT_TRUE(GetDeletedNodeRoot()->empty());
EXPECT_TRUE(GetPendingNodeRoot()->empty());
}


TEST_F(BraveBookmarkChangeProcessorTest, DISABLED_InitialSync) {
// BookmarkChangeProcessor::InitialSync does not do anything now
// All work for obtaining order is done in background.js
Expand Down
5 changes: 4 additions & 1 deletion components/brave_sync/model/change_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class ChangeProcessor {
virtual void Stop() = 0;

// reset all sync data, but do not delete local records
virtual void Reset() = 0;
// with clear_meta_info == false, we perserve meta info for reconnecting to
// previous sync chain and only clear permanent nodes managed by sync.
// If we want to connect/create to new sync chain, we should clear meta info.
virtual void Reset(bool clear_meta_info) = 0;

// setup permanent nodes
virtual void InitialSync() = 0;
Expand Down

0 comments on commit 27f2159

Please sign in to comment.