From e023ebbc097a266e91ae1adbf56ec87cf1fa32c0 Mon Sep 17 00:00:00 2001 From: AlexeyBarabash Date: Mon, 4 Feb 2019 17:08:52 +0200 Subject: [PATCH 1/3] Do not call ResetSyncInternal twice; fixes brave-browser#3188 --- .../brave_sync/brave_sync_service_impl.cc | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/components/brave_sync/brave_sync_service_impl.cc b/components/brave_sync/brave_sync_service_impl.cc index cb76609e0f92..24041c2516b8 100644 --- a/components/brave_sync/brave_sync_service_impl.cc +++ b/components/brave_sync/brave_sync_service_impl.cc @@ -228,11 +228,12 @@ void BraveSyncServiceImpl::OnResetSync() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); auto sync_devices = sync_prefs_->GetSyncDevices(); - // If there is only one or no devices left, we won't get back resolved sync - // record back. - if (sync_devices->size() <= 1) + + if (sync_devices->size() == 0) { + // Fail safe option + VLOG(2) << "[Sync] " << __func__ << " unexpected zero device size"; ResetSyncInternal(); - else { + } else { // We have to send delete record and wait for library deleted response then // we can reset it by ResetInternal() const std::string device_id = sync_prefs_->GetThisDeviceId(); @@ -365,12 +366,20 @@ void BraveSyncServiceImpl::OnSaveInitData(const Uint8Array& seed, sync_words_.clear(); DCHECK(!seed_str.empty()); - if (prev_seed_str == seed_str) { // reconnecitng to previous sync chain + + if (prev_seed_str == seed_str) { // reconnecting 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 + } else { + // This is not required, because when there is no previous seed, bookmarks + // should not have a metadata. However, this is done by intention, to be + // a remedy for cases when sync had been reset and prev_seed_str had been + // cleared when it shouldn't (brave-browser#3188). + bookmark_change_processor_->Reset(true); + } + sync_prefs_->SetSeed(seed_str); sync_prefs_->SetThisDeviceId(device_id_str); @@ -492,10 +501,14 @@ void BraveSyncServiceImpl::OnResolvedPreferences(const RecordsList& records) { sync_prefs_->SetSyncDevices(*sync_devices); - if (this_device_deleted) + if (this_device_deleted) { ResetSyncInternal(); - if (contains_only_one_device) + } else if (contains_only_one_device) { + // We see amount of devices had been decreased to 1 and it is not this + // device had been deleted. So call OnResetSync which will send DELETE + // record for this device OnResetSync(); + } } void BraveSyncServiceImpl::OnSyncPrefsChanged(const std::string& pref) { From 59af5a1c210ba2f69ea2a5b643cbf674e284468d Mon Sep 17 00:00:00 2001 From: AlexeyBarabash Date: Mon, 4 Feb 2019 17:12:38 +0200 Subject: [PATCH 2/3] Unit test change for don't call ResetSyncInternal twice fix --- .../brave_sync/brave_sync_service_unittest.cc | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/components/brave_sync/brave_sync_service_unittest.cc b/components/brave_sync/brave_sync_service_unittest.cc index 37468429520b..22c39bfd72ce 100644 --- a/components/brave_sync/brave_sync_service_unittest.cc +++ b/components/brave_sync/brave_sync_service_unittest.cc @@ -490,13 +490,29 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { 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(3); + // Expecting to be called one time to set the new devices list + EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); + + EXPECT_CALL(*sync_client(), SendSyncRecords).Times(1); + sync_service()->OnResolvedPreferences(resolved_records); + auto devices_semi_final = sync_service()->sync_prefs_->GetSyncDevices(); + EXPECT_FALSE(DevicesContains(devices_semi_final.get(), "2", "device2")); + EXPECT_TRUE(DevicesContains(devices_semi_final.get(), "1", "device1")); + + // Emulate sending DELETE for this device + RecordsList resolved_records2; + auto resolved_record2 = SyncRecord::Clone(*records.at(0)); + resolved_record2->action = SyncRecord::Action::A_DELETE; + resolved_records2.push_back(std::move(resolved_record2)); + EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(3); + + sync_service()->OnResolvedPreferences(resolved_records2); + auto devices_final = sync_service()->sync_prefs_->GetSyncDevices(); EXPECT_FALSE(DevicesContains(devices_final.get(), "1", "device1")); EXPECT_FALSE(DevicesContains(devices_final.get(), "2", "device2")); - EXPECT_FALSE(sync_service()->IsSyncConfigured()); } @@ -526,7 +542,8 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { auto 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(5); + // If you have to modify .Times(3) to another value, double re-check + EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(3); sync_service()->OnResolvedPreferences(resolved_records); auto devices_final = sync_service()->sync_prefs_->GetSyncDevices(); From 2340132e3edbe68b00d83ea8fb6bb8ddd20da731 Mon Sep 17 00:00:00 2001 From: AlexeyBarabash Date: Mon, 4 Feb 2019 18:50:46 +0200 Subject: [PATCH 3/3] Lint fixes --- .../brave_sync/brave_sync_service_impl.cc | 35 ++++--- .../brave_sync/brave_sync_service_unittest.cc | 91 ++++++++++--------- 2 files changed, 71 insertions(+), 55 deletions(-) diff --git a/components/brave_sync/brave_sync_service_impl.cc b/components/brave_sync/brave_sync_service_impl.cc index 24041c2516b8..8ea579218887 100644 --- a/components/brave_sync/brave_sync_service_impl.cc +++ b/components/brave_sync/brave_sync_service_impl.cc @@ -1,9 +1,15 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* Copyright 2016 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "brave/components/brave_sync/brave_sync_service_impl.h" +#include +#include +#include +#include + #include "base/task/post_task.h" #include "brave/browser/ui/webui/sync/sync_ui.h" #include "brave/components/brave_sync/bookmark_order_util.h" @@ -40,7 +46,7 @@ RecordsListPtr CreateDeviceCreationRecordExtension( record->action = action; record->deviceId = deviceId; record->objectId = objectId; - record->objectData = jslib_const::SyncObjectData_DEVICE; // "device" + record->objectData = jslib_const::SyncObjectData_DEVICE; // "device" std::unique_ptr device = std::make_unique(); device->name = deviceName; @@ -62,7 +68,7 @@ SyncRecordPtr PrepareResolvedDevice( brave_sync::jslib::SyncRecord::Action::A_INVALID); record->deviceId = device->device_id_; record->objectId = device->object_id_; - record->objectData = jslib_const::SyncObjectData_DEVICE; // "device" + record->objectData = jslib_const::SyncObjectData_DEVICE; // "device" std::unique_ptr device_record = std::make_unique(); @@ -367,9 +373,9 @@ void BraveSyncServiceImpl::OnSaveInitData(const Uint8Array& seed, sync_words_.clear(); DCHECK(!seed_str.empty()); - if (prev_seed_str == seed_str) { // reconnecting to previous sync chain + if (prev_seed_str == seed_str) { // reconnecting to previous sync chain sync_prefs_->SetPrevSeed(std::string()); - } else if (!prev_seed_str.empty()) { // connect/create to new sync chain + } else if (!prev_seed_str.empty()) { // connect/create to new sync chain bookmark_change_processor_->Reset(true); sync_prefs_->SetPrevSeed(std::string()); } else { @@ -450,7 +456,6 @@ void BraveSyncServiceImpl::OnResolvedSyncRecords( } else if (category_name == brave_sync::jslib_const::kHistorySites) { NOTIMPLEMENTED(); } - } std::unique_ptr @@ -497,7 +502,7 @@ void BraveSyncServiceImpl::OnResolvedPreferences(const RecordsList& records) { record->action == jslib::SyncRecord::Action::A_DELETE && actually_merged; } - } // for each device + } // for each device sync_prefs_->SetSyncDevices(*sync_devices); @@ -571,15 +576,17 @@ void BraveSyncServiceImpl::FetchSyncRecords(const bool bookmarks, } std::vector category_names; - using namespace brave_sync::jslib_const; + using brave_sync::jslib_const::kHistorySites; + using brave_sync::jslib_const::kBookmarks; + using brave_sync::jslib_const::kPreferences; if (history) { - category_names.push_back(kHistorySites); // "HISTORY_SITES"; + category_names.push_back(kHistorySites); // "HISTORY_SITES"; } if (bookmarks) { - category_names.push_back(kBookmarks);//"BOOKMARKS"; + category_names.push_back(kBookmarks); // "BOOKMARKS"; } if (preferences) { - category_names.push_back(kPreferences);//"PREFERENCES"; + category_names.push_back(kPreferences); // "PREFERENCES"; } DCHECK(sync_client_); @@ -707,4 +714,4 @@ void BraveSyncServiceImpl::SetDeviceName(const std::string& name) { } } -} // namespace brave_sync +} // namespace brave_sync diff --git a/components/brave_sync/brave_sync_service_unittest.cc b/components/brave_sync/brave_sync_service_unittest.cc index 22c39bfd72ce..9264554a66ae 100644 --- a/components/brave_sync/brave_sync_service_unittest.cc +++ b/components/brave_sync/brave_sync_service_unittest.cc @@ -1,6 +1,7 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* Copyright 2016 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "base/files/scoped_temp_dir.h" #include "base/strings/utf_string_conversions.h" @@ -87,11 +88,17 @@ // | BraveSyncServiceTest.OnResetSync // OnSyncPrefsChanged | + -using testing::_; -using testing::AtLeast; -using namespace brave_sync; +using brave_sync::BraveSyncService; +using brave_sync::BraveSyncServiceImpl; +using brave_sync::BraveSyncServiceObserver; +using brave_sync::jslib::SyncRecord; +using brave_sync::MockBraveSyncClient; +using brave_sync::RecordsList; +using brave_sync::SimpleDeviceRecord; using network::TestNetworkConnectionTracker; using network::mojom::ConnectionType; +using testing::_; +using testing::AtLeast; class MockBraveSyncServiceObserver : public BraveSyncServiceObserver { public: @@ -114,20 +121,22 @@ class BraveSyncServiceTest EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); // register the factory - profile_ = CreateBraveSyncProfile(temp_dir_.GetPath()); + profile_ = brave_sync::CreateBraveSyncProfile(temp_dir_.GetPath()); EXPECT_TRUE(profile_.get() != NULL); // TODO(bridiver) - this is temporary until some changes are made to // to bookmark_change_processor to allow `set_for_testing` like // BraveSyncClient BookmarkModelFactory::GetInstance()->SetTestingFactory( - profile(), base::BindRepeating(&BuildFakeBookmarkModelForTests)); + profile(), + base::BindRepeating(&brave_sync::BuildFakeBookmarkModelForTests)); - BraveSyncClientImpl::set_for_testing( + brave_sync::BraveSyncClientImpl::set_for_testing( new MockBraveSyncClient()); sync_service_ = static_cast( - BraveSyncServiceFactory::GetInstance()->GetForProfile(profile())); + brave_sync::BraveSyncServiceFactory::GetInstance()->GetForProfile( + profile())); sync_client_ = static_cast(sync_service_->GetSyncClient()); @@ -219,7 +228,8 @@ void BraveSyncServiceTest::BookmarkAddedImpl() { // Invoke BraveSyncService::BookmarkAdded // Expect BraveSyncClient::SendSyncRecords invoked EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); - EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(AtLeast(1)); + EXPECT_CALL(*observer(), + OnSyncStateChanged(sync_service())).Times(AtLeast(1)); sync_service()->OnSetupSyncNewToSync("UnitTestBookmarkAdded"); sync_service()->BackgroundSyncStarted(true/*startup*/); @@ -228,7 +238,7 @@ void BraveSyncServiceTest::BookmarkAddedImpl() { GURL("https://a.com"), base::ASCIIToUTF16("A.com - title")); // Force service send bookmarks and fire the mock - EXPECT_CALL(*sync_client(), SendSyncRecords(_,_)).Times(1); + EXPECT_CALL(*sync_client(), SendSyncRecords(_, _)).Times(1); sync_service()->OnResolvedSyncRecords(brave_sync::jslib_const::kBookmarks, std::make_unique()); } @@ -246,7 +256,8 @@ TEST_F(BraveSyncServiceTest, BookmarkDeleted) { bookmarks::GetMostRecentlyAddedEntries(bookmark_model, 1, &nodes); ASSERT_EQ(nodes.size(), 1u); ASSERT_NE(nodes.at(0), nullptr); - EXPECT_CALL(*sync_client(), SendSyncRecords(_,_)).Times(1); // TODO, AB: preciece with mock expect filter + // TODO(alexeyb): preciece with mock expect filter + EXPECT_CALL(*sync_client(), SendSyncRecords(_, _)).Times(1); bookmark_model->Remove(nodes.at(0)); // record->action = jslib::SyncRecord::Action::A_DELETE; // <= BookmarkNodeToSyncBookmark <= BookmarkChangeProcessor::SendUnsynced @@ -347,8 +358,8 @@ TEST_F(BraveSyncServiceTest, GetSettingsAndDevices) { EXPECT_FALSE(settings->sync_settings_); EXPECT_FALSE(settings->sync_history_); EXPECT_EQ(devices->size(), 0u); - } - ); + }); + sync_service()->GetSettingsAndDevices(callback1); EXPECT_CALL(*sync_client(), OnSyncEnabledChanged); // Expecting sync state changed twice: for enabled state and for device name @@ -362,8 +373,7 @@ TEST_F(BraveSyncServiceTest, GetSettingsAndDevices) { // Other fields may be switched later EXPECT_EQ(settings->this_device_name_, "test_device"); EXPECT_TRUE(settings->sync_this_device_); - } - ); + }); sync_service()->GetSettingsAndDevices(callback2); } @@ -386,25 +396,26 @@ TEST_F(BraveSyncServiceTest, SyncSetupError) { TEST_F(BraveSyncServiceTest, GetSeed) { EXPECT_CALL(*sync_client(), OnSyncEnabledChanged); - EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(AtLeast(2)); + EXPECT_CALL(*observer(), + OnSyncStateChanged(sync_service())).Times(AtLeast(2)); sync_service()->OnSetupSyncNewToSync("test_device"); EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncEnabled)); // Service gets seed from client via BraveSyncServiceImpl::OnSaveInitData - const auto binary_seed = Uint8Array(16, 77); + const auto binary_seed = brave_sync::Uint8Array(16, 77); EXPECT_TRUE(sync_service()->sync_prefs_->GetPrevSeed().empty()); sync_service()->OnSaveInitData(binary_seed, {0}); - std::string expected_seed = StrFromUint8Array(binary_seed); + std::string expected_seed = brave_sync::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, +bool DevicesContains(brave_sync::SyncDevices* devices, const std::string& id, const std::string& name) { DCHECK(devices); - for (const SyncDevice &device : devices->devices_) { + for (const auto& device : devices->devices_) { if (device.device_id_ == id && device.name_ == name) { return true; } @@ -429,13 +440,13 @@ MATCHER_P2(ContainsDeviceRecord, action, name, TEST_F(BraveSyncServiceTest, OnDeleteDevice) { RecordsList records; records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "1", "device1")); records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "2", "device2")); records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "3", "device3")); EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); sync_service()->OnResolvedPreferences(records); @@ -447,14 +458,13 @@ TEST_F(BraveSyncServiceTest, OnDeleteDevice) { EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2")); EXPECT_TRUE(DevicesContains(devices.get(), "3", "device3")); - using brave_sync::jslib::SyncRecord; EXPECT_CALL(*sync_client(), SendSyncRecords("PREFERENCES", ContainsDeviceRecord(SyncRecord::Action::A_DELETE, "device3"))).Times(1); sync_service()->OnDeleteDevice("3"); RecordsList resolved_records; auto resolved_record = SyncRecord::Clone(*records.at(2)); - resolved_record->action = jslib::SyncRecord::Action::A_DELETE; + resolved_record->action = 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); @@ -469,10 +479,10 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { sync_service()->sync_prefs_->SetThisDeviceId("1"); RecordsList records; records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "1", "device1")); records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "2", "device2")); EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); sync_service()->OnResolvedPreferences(records); @@ -482,13 +492,12 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1")); EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2")); - using brave_sync::jslib::SyncRecord; EXPECT_CALL(*sync_client(), SendSyncRecords).Times(1); sync_service()->OnDeleteDevice("2"); RecordsList resolved_records; auto resolved_record = SyncRecord::Clone(*records.at(1)); - resolved_record->action = jslib::SyncRecord::Action::A_DELETE; + resolved_record->action = SyncRecord::Action::A_DELETE; resolved_records.push_back(std::move(resolved_record)); // Expecting to be called one time to set the new devices list EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); @@ -520,10 +529,10 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { sync_service()->sync_prefs_->SetThisDeviceId("1"); RecordsList records; records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "1", "device1")); records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "2", "device2")); EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); sync_service()->OnResolvedPreferences(records); @@ -533,14 +542,13 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1")); EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2")); - using brave_sync::jslib::SyncRecord; EXPECT_CALL(*sync_client(), SendSyncRecords("PREFERENCES", ContainsDeviceRecord(SyncRecord::Action::A_DELETE, "device1"))).Times(1); sync_service()->OnDeleteDevice("1"); RecordsList resolved_records; auto resolved_record = SyncRecord::Clone(*records.at(0)); - resolved_record->action = jslib::SyncRecord::Action::A_DELETE; + resolved_record->action = SyncRecord::Action::A_DELETE; resolved_records.push_back(std::move(resolved_record)); // If you have to modify .Times(3) to another value, double re-check EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(3); @@ -555,7 +563,8 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { TEST_F(BraveSyncServiceTest, OnResetSync) { EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(AtLeast(1)); - EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(AtLeast(3)); + EXPECT_CALL(*observer(), + OnSyncStateChanged(sync_service())).Times(AtLeast(3)); sync_service()->OnSetupSyncNewToSync("this_device"); EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncEnabled)); @@ -563,10 +572,10 @@ TEST_F(BraveSyncServiceTest, OnResetSync) { RecordsList records; records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "0", "this_device")); records.push_back(SimpleDeviceRecord( - jslib::SyncRecord::Action::A_CREATE, + SyncRecord::Action::A_CREATE, "1", "device1")); sync_service()->OnResolvedPreferences(records); @@ -578,8 +587,8 @@ TEST_F(BraveSyncServiceTest, OnResetSync) { sync_service()->OnResetSync(); RecordsList resolved_records; - auto resolved_record = jslib::SyncRecord::Clone(*records.at(0)); - resolved_record->action = jslib::SyncRecord::Action::A_DELETE; + auto resolved_record = SyncRecord::Clone(*records.at(0)); + resolved_record->action = SyncRecord::Action::A_DELETE; resolved_records.push_back(std::move(resolved_record)); sync_service()->OnResolvedPreferences(resolved_records); @@ -700,7 +709,7 @@ TEST_F(BraveSyncServiceTest, OnGetExistingObjects) { EXPECT_CALL(*sync_client(), SendResolveSyncRecords).Times(1); auto records = std::make_unique(); - sync_service()->OnGetExistingObjects(jslib_const::kBookmarks, + sync_service()->OnGetExistingObjects(brave_sync::jslib_const::kBookmarks, std::move(records), base::Time(), false);