diff --git a/DEPS b/DEPS index 2cb41fc8b19c..983fb25714e5 100644 --- a/DEPS +++ b/DEPS @@ -15,7 +15,7 @@ deps = { "vendor/bip39wally-core-native": "https://github.com/brave-intl/bip39wally-core-native.git@13bb40a215248cfbdd87d0a6b425c8397402e9e6", "vendor/bat-native-anonize": "https://github.com/brave-intl/bat-native-anonize.git@e3742ba3e8942eea9e4755d91532491871bd3116", "vendor/bat-native-tweetnacl": "https://github.com/brave-intl/bat-native-tweetnacl.git@1b4362968c8f22720bfb75af6f506d4ecc0f3116", - "components/brave_sync/extension/brave-sync": "https://github.com/brave/sync.git@e97e9e912552cd789cb2c1b1f327c77b32175317", + "components/brave_sync/extension/brave-sync": "https://github.com/brave/sync.git@91a68fdebc8962ca409045177438671f06a3c26a", "components/brave_sync/extension/brave-crypto": "https://github.com/brave/crypto@0231e65ba211b152d742278319c545a83cb13fc0", "vendor/bat-native-usermodel": "https://github.com/brave-intl/bat-native-usermodel.git@c1745b906079285fc01e3079ac49b0e65fde0f98", "vendor/challenge_bypass_ristretto_ffi": "https://github.com/brave-intl/challenge-bypass-ristretto-ffi.git@f88d942ddfaf61a4a6703355a77c4ef71bc95c35", diff --git a/browser/BUILD.gn b/browser/BUILD.gn index 86db565e59b5..04b7ed4c8c8b 100644 --- a/browser/BUILD.gn +++ b/browser/BUILD.gn @@ -21,8 +21,6 @@ source_set("browser_process") { "autocomplete/brave_autocomplete_provider_client.h", "autocomplete/brave_autocomplete_scheme_classifier.cc", "autocomplete/brave_autocomplete_scheme_classifier.h", - "bookmarks/brave_bookmark_client.cc", - "bookmarks/brave_bookmark_client.h", "brave_browser_main_extra_parts.cc", "brave_browser_main_extra_parts.h", "brave_browser_main_parts.cc", diff --git a/browser/autocomplete/brave_autocomplete_provider_client_unittest.cc b/browser/autocomplete/brave_autocomplete_provider_client_unittest.cc index 5a4d4344250b..7f2565d0467e 100644 --- a/browser/autocomplete/brave_autocomplete_provider_client_unittest.cc +++ b/browser/autocomplete/brave_autocomplete_provider_client_unittest.cc @@ -1,13 +1,20 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 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/browser/autocomplete/brave_autocomplete_provider_client.h" +#include +#include +#include + #include "base/strings/utf_string_conversions.h" #include "brave/common/webui_url_constants.h" +#include "chrome/browser/prefs/browser_prefs.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/testing_profile.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/test/fake_service_worker_context.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -15,7 +22,7 @@ class BraveAutocompleteProviderClientUnitTest : public testing::Test { public: void SetUp() override { - profile_ = std::make_unique(); + profile_ = CreateProfile(); client_ = std::make_unique(profile_.get()); } @@ -26,7 +33,16 @@ class BraveAutocompleteProviderClientUnitTest : public testing::Test { return it != v.end(); } - protected: + private: + std::unique_ptr CreateProfile() { + TestingProfile::Builder builder; + auto prefs = + std::make_unique(); + RegisterUserProfilePrefs(prefs->registry()); + builder.SetPrefService(std::move(prefs)); + return builder.Build(); + } + content::TestBrowserThreadBundle test_browser_thread_bundle_; std::unique_ptr profile_; std::unique_ptr client_; @@ -34,6 +50,7 @@ class BraveAutocompleteProviderClientUnitTest : public testing::Test { TEST_F(BraveAutocompleteProviderClientUnitTest, SyncURLSuggestedNotSyncInternal) { - ASSERT_FALSE(BuiltinExists(base::ASCIIToUTF16(chrome::kChromeUISyncInternalsHost))); + ASSERT_FALSE( + BuiltinExists(base::ASCIIToUTF16(chrome::kChromeUISyncInternalsHost))); ASSERT_TRUE(BuiltinExists(base::ASCIIToUTF16(kBraveUISyncHost))); } diff --git a/browser/autoplay/autoplay_permission_context_unittest.cc b/browser/autoplay/autoplay_permission_context_unittest.cc index 9b5cd5b0f983..ab4d802b67cb 100644 --- a/browser/autoplay/autoplay_permission_context_unittest.cc +++ b/browser/autoplay/autoplay_permission_context_unittest.cc @@ -11,7 +11,6 @@ #include "base/bind.h" #include "base/macros.h" -#include "brave/common/pref_names.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/permissions/permission_request_id.h" #include "chrome/browser/permissions/permission_request_manager.h" @@ -77,8 +76,6 @@ class AutoplayPermissionContextTests : public ChromeRenderViewHostTestHarness { auto prefs = std::make_unique(); RegisterUserProfilePrefs(prefs->registry()); - prefs->registry()-> - RegisterBooleanPref(kGoogleLoginControlType, true); builder.SetPrefService(std::move(prefs)); return builder.Build().release(); } diff --git a/browser/bookmarks/brave_bookmark_client.cc b/browser/bookmarks/brave_bookmark_client.cc deleted file mode 100644 index 4a5e49d88c41..000000000000 --- a/browser/bookmarks/brave_bookmark_client.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* 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/browser/bookmarks/brave_bookmark_client.h" - -#include "brave/components/brave_sync/buildflags/buildflags.h" -#include "chrome/browser/profiles/profile.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "components/bookmarks/managed/managed_bookmark_service.h" -#include "components/sync_bookmarks/bookmark_sync_service.h" - -#if BUILDFLAG(ENABLE_BRAVE_SYNC) -#include "brave/components/brave_sync/brave_sync_service.h" -#endif - -BraveBookmarkClient::BraveBookmarkClient( - Profile* profile, - bookmarks::ManagedBookmarkService* managed_bookmark_service, - sync_bookmarks::BookmarkSyncService* bookmark_sync_service) - : ChromeBookmarkClient(profile, - managed_bookmark_service, - bookmark_sync_service) {} - -bookmarks::LoadExtraCallback BraveBookmarkClient::GetLoadExtraNodesCallback() { -#if BUILDFLAG(ENABLE_BRAVE_SYNC) - return base::BindOnce(&brave_sync::LoadExtraNodes, - ChromeBookmarkClient::GetLoadExtraNodesCallback()); -#endif - return ChromeBookmarkClient::GetLoadExtraNodesCallback(); -} - -bool BraveBookmarkClient::IsPermanentNodeVisible( - const bookmarks::BookmarkPermanentNode* node) { -#if BUILDFLAG(ENABLE_BRAVE_SYNC) - if (brave_sync::IsSyncManagedNode(node)) - return false; // don't display sync managed nodes -#endif - return ChromeBookmarkClient::IsPermanentNodeVisible(node); -} diff --git a/browser/bookmarks/brave_bookmark_client.h b/browser/bookmarks/brave_bookmark_client.h deleted file mode 100644 index ed3e7a96d99e..000000000000 --- a/browser/bookmarks/brave_bookmark_client.h +++ /dev/null @@ -1,25 +0,0 @@ -/* 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/. */ - -#ifndef BRAVE_BROWSER_BOOKMARKS_BRAVE_BOOKMARK_CLIENT_H_ -#define BRAVE_BROWSER_BOOKMARKS_BRAVE_BOOKMARK_CLIENT_H_ - -#include "chrome/browser/bookmarks/chrome_bookmark_client.h" - -class BraveBookmarkClient : public ChromeBookmarkClient { - public: - BraveBookmarkClient( - Profile* profile, - bookmarks::ManagedBookmarkService* managed_bookmark_service, - sync_bookmarks::BookmarkSyncService* bookmark_sync_service); - - bookmarks::LoadExtraCallback GetLoadExtraNodesCallback() override; - bool IsPermanentNodeVisible( - const bookmarks::BookmarkPermanentNode* node) override; - - private: - DISALLOW_COPY_AND_ASSIGN(BraveBookmarkClient); -}; - -#endif // BRAVE_BROWSER_BOOKMARKS_BRAVE_BOOKMARK_CLIENT_H_ diff --git a/browser/brave_content_browser_client_browsertest.cc b/browser/brave_content_browser_client_browsertest.cc index d29f4076eedc..fbde5e1fda3b 100644 --- a/browser/brave_content_browser_client_browsertest.cc +++ b/browser/brave_content_browser_client_browsertest.cc @@ -13,6 +13,7 @@ #include "brave/common/pref_names.h" #include "brave/components/brave_rewards/browser/buildflags/buildflags.h" #include "brave/components/brave_shields/common/brave_shield_constants.h" +#include "brave/components/brave_sync/buildflags/buildflags.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" @@ -151,9 +152,11 @@ IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, CanLoadCustomBravePages) { std::vector pages { "adblock", #if BUILDFLAG(BRAVE_REWARDS_ENABLED) - "rewards", + "rewards", +#endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) + chrome::kChromeUISyncHost, #endif - chrome::kChromeUISyncHost, }; std::vector schemes { @@ -205,6 +208,7 @@ IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, CanLoadAboutHost) { } } +#if BUILDFLAG(ENABLE_BRAVE_SYNC) IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteChromeSyncInternals) { std::vector schemes { @@ -230,6 +234,7 @@ IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, "chrome://sync/"); } } +#endif IN_PROC_BROWSER_TEST_F(BraveContentBrowserClientTest, RewriteWelcomeWin10Host) { diff --git a/browser/brave_profile_prefs.cc b/browser/brave_profile_prefs.cc index 6e5ecac3df1a..35659b2cf709 100644 --- a/browser/brave_profile_prefs.cc +++ b/browser/brave_profile_prefs.cc @@ -5,11 +5,9 @@ #include "brave/browser/brave_profile_prefs.h" -#include "brave/browser/themes/brave_theme_service.h" -#include "brave/browser/tor/buildflags.h" #include "brave/common/pref_names.h" -#include "brave/components/brave_rewards/browser/rewards_service.h" #include "brave/components/brave_shields/browser/brave_shields_web_contents_observer.h" +#include "brave/components/brave_sync/brave_sync_prefs.h" #include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h" #include "chrome/browser/net/prediction_options.h" #include "chrome/browser/prefs/session_startup_pref.h" @@ -18,7 +16,6 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/signin/core/browser/signin_pref_names.h" -#include "components/spellcheck/browser/pref_names.h" #include "components/sync/base/pref_names.h" #include "extensions/buildflags/buildflags.h" #include "extensions/common/feature_switch.h" @@ -32,29 +29,19 @@ #include "brave/components/brave_webtorrent/browser/webtorrent_util.h" #endif -#if BUILDFLAG(ENABLE_TOR) -#include "brave/browser/tor/tor_profile_service.h" -#endif - using extensions::FeatureSwitch; namespace brave { void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { - brave_rewards::RewardsService::RegisterProfilePrefs(registry); brave_shields::BraveShieldsWebContentsObserver::RegisterProfilePrefs( registry); // appearance -#if !defined(OS_ANDROID) - BraveThemeService::RegisterProfilePrefs(registry); -#endif registry->RegisterBooleanPref(kLocationBarIsWide, false); registry->RegisterBooleanPref(kHideBraveRewardsButton, false); -#if BUILDFLAG(ENABLE_TOR) - tor::TorProfileService::RegisterProfilePrefs(registry); -#endif + brave_sync::prefs::Prefs::RegisterProfilePrefs(registry); registry->RegisterBooleanPref(kWidevineOptedIn, false); #if BUILDFLAG(BUNDLE_WIDEVINE_CDM) @@ -75,11 +62,6 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { webtorrent::RegisterProfilePrefs(registry); #endif -#if defined(OS_LINUX) - // Use brave theme by default instead of gtk theme. - registry->SetDefaultPrefValue(prefs::kUsesSystemTheme, base::Value(false)); -#endif - // Hangouts registry->RegisterBooleanPref(kHangoutsEnabled, true); @@ -95,9 +77,6 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { FeatureSwitch::load_media_router_component_extension()->IsEnabled()); #endif - // No sign into Brave functionality - registry->SetDefaultPrefValue(prefs::kSigninAllowed, base::Value(false)); - // Restore last profile on restart registry->SetDefaultPrefValue( prefs::kRestoreOnStartup, @@ -110,10 +89,6 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { registry->SetDefaultPrefValue(prefs::kAlternateErrorPagesEnabled, base::Value(false)); - // Disable spell check service - registry->SetDefaultPrefValue( - spellcheck::prefs::kSpellCheckUseSpellingService, base::Value(false)); - // Disable safebrowsing reporting registry->SetDefaultPrefValue( prefs::kSafeBrowsingExtendedReportingOptInAllowed, base::Value(false)); @@ -130,12 +105,6 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { // Make sync managed to dsiable some UI after password saving. registry->SetDefaultPrefValue(syncer::prefs::kSyncManaged, base::Value(true)); - // Make sure sign into Brave is not enabled - // The older kSigninAllowed is deprecated and only in use in Android until - // C71. - registry->SetDefaultPrefValue(prefs::kSigninAllowedOnNextStartup, - base::Value(false)); - // Disable cloud print // Cloud Print: Don't allow this browser to act as Cloud Print server registry->SetDefaultPrefValue(prefs::kCloudPrintProxyEnabled, diff --git a/browser/browser_context_keyed_service_factories.cc b/browser/browser_context_keyed_service_factories.cc index 029b7f47cadb..05f278713614 100644 --- a/browser/browser_context_keyed_service_factories.cc +++ b/browser/browser_context_keyed_service_factories.cc @@ -10,14 +10,12 @@ #include "brave/browser/tor/tor_profile_service_factory.h" #include "brave/components/brave_ads/browser/ads_service_factory.h" #include "brave/components/brave_rewards/browser/rewards_service_factory.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" namespace brave { void EnsureBrowserContextKeyedServiceFactoriesBuilt() { brave_ads::AdsServiceFactory::GetInstance(); brave_rewards::RewardsServiceFactory::GetInstance(); - brave_sync::BraveSyncServiceFactory::GetInstance(); greaselion::GreaselionServiceFactory::GetInstance(); TorProfileServiceFactory::GetInstance(); SearchEngineProviderServiceFactory::GetInstance(); diff --git a/browser/extensions/BUILD.gn b/browser/extensions/BUILD.gn index 598b2f09fc12..a4039d9bee42 100644 --- a/browser/extensions/BUILD.gn +++ b/browser/extensions/BUILD.gn @@ -1,32 +1,27 @@ import("//brave/components/brave_rewards/browser/buildflags/buildflags.gni") +import("//brave/components/brave_sync/buildflags/buildflags.gni") import("//brave/components/brave_wallet/browser/buildflags/buildflags.gni") import("//brave/components/brave_webtorrent/browser/buildflags/buildflags.gni") import("//build/config/features.gni") source_set("extensions") { sources = [ - "api/rewards_notifications_api.cc", - "api/rewards_notifications_api.h", "api/brave_extensions_api_client.cc", "api/brave_extensions_api_client.h", "api/brave_rewards_api.cc", "api/brave_rewards_api.h", "api/brave_shields_api.cc", "api/brave_shields_api.h", - "api/brave_sync_api.cc", - "api/brave_sync_api.h", - "api/brave_sync_event_router.cc", - "api/brave_sync_event_router.h", "api/brave_theme_api.cc", "api/brave_theme_api.h", + "api/rewards_notifications_api.cc", + "api/rewards_notifications_api.h", "api/settings_private/brave_prefs_util.cc", "api/settings_private/brave_prefs_util.h", "brave_component_extension_resource_manager.cc", "brave_component_extension_resource_manager.h", "brave_component_loader.cc", "brave_component_loader.h", - "brave_extensions_browser_api_provider.cc", - "brave_extensions_browser_api_provider.h", "brave_extension_install_prompt.cc", "brave_extension_install_prompt.h", "brave_extension_management.cc", @@ -35,12 +30,14 @@ source_set("extensions") { "brave_extension_provider.h", "brave_extension_service.cc", "brave_extension_service.h", + "brave_extensions_browser_api_provider.cc", + "brave_extensions_browser_api_provider.h", "brave_theme_event_router.cc", "brave_theme_event_router.h", "brave_tor_client_updater.cc", "brave_tor_client_updater.h", "updater/brave_update_client_config.cc", - "updater/brave_update_client_config.h" + "updater/brave_update_client_config.h", ] if (brave_wallet_enabled) { @@ -58,11 +55,8 @@ source_set("extensions") { "//brave/common:pref_names", "//brave/common/extensions/api", "//brave/components/brave_component_updater/browser", - "//brave/components/brave_extension:static_resources", "//brave/components/brave_extension:generated_resources", - "//brave/components/brave_sync", - "//brave/components/brave_sync:generated_resources", - "//brave/components/brave_sync:static_resources", + "//brave/components/brave_extension:static_resources", "//components/prefs", "//components/update_client:patch_impl", "//components/update_client:unzip_impl", @@ -78,6 +72,20 @@ source_set("extensions") { "//brave/components/brave_rewards/resources/extension:static_resources", ] } + if (enable_brave_sync) { + sources += [ + "api/brave_sync_api.cc", + "api/brave_sync_api.h", + "api/brave_sync_event_router.cc", + "api/brave_sync_event_router.h", + ] + + deps += [ + "//brave/components/brave_sync", + "//brave/components/brave_sync:generated_resources", + "//brave/components/brave_sync:static_resources", + ] + } if (enable_brave_webtorrent) { deps += [ "//brave/components/brave_webtorrent:generated_resources", diff --git a/browser/extensions/api/brave_sync_api.cc b/browser/extensions/api/brave_sync_api.cc index da656c73f435..d7e3448ede32 100644 --- a/browser/extensions/api/brave_sync_api.cc +++ b/browser/extensions/api/brave_sync_api.cc @@ -10,16 +10,17 @@ #include #include "brave/common/extensions/api/brave_sync.h" -#include "brave/components/brave_sync/client/brave_sync_client.h" #include "brave/components/brave_sync/brave_sync_service.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" +#include "brave/components/brave_sync/client/brave_sync_client.h" #include "brave/components/brave_sync/client/client_ext_impl_data.h" -#include "brave/components/brave_sync/values_conv.h" #include "brave/components/brave_sync/jslib_messages.h" +#include "brave/components/brave_sync/public/brave_profile_sync_service.h" +#include "brave/components/brave_sync/values_conv.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" -using ::brave_sync::BraveSyncService; -using ::brave_sync::BraveSyncServiceFactory; +using brave_sync::BraveProfileSyncService; +using brave_sync::BraveSyncService; using content::BrowserContext; namespace extensions { @@ -27,9 +28,15 @@ namespace api { namespace { -BraveSyncService* GetBraveSyncService(BrowserContext* browser_context) { - return BraveSyncServiceFactory::GetForProfile( - Profile::FromBrowserContext(browser_context)); +BraveProfileSyncService* GetProfileSyncService( + BrowserContext* browser_context) { + return static_cast( + ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile( + Profile::FromBrowserContext(browser_context))); +} + +BraveSyncService* GetSyncService(BrowserContext* browser_context) { + return GetProfileSyncService(browser_context)->GetSyncService(); } } // namespace @@ -38,9 +45,9 @@ ExtensionFunction::ResponseAction BraveSyncGetInitDataFunction::Run() { brave_sync::GetInitData::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnGetInitData( + sync_service->GetBraveSyncClient()->sync_message_handler()->OnGetInitData( params->sync_version); return RespondNow(NoArguments()); @@ -51,9 +58,9 @@ ExtensionFunction::ResponseAction BraveSyncSyncSetupErrorFunction::Run() { brave_sync::SyncSetupError::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnSyncSetupError( + sync_service->GetBraveSyncClient()->sync_message_handler()->OnSyncSetupError( params->error); return RespondNow(NoArguments()); @@ -64,9 +71,9 @@ ExtensionFunction::ResponseAction BraveSyncSyncDebugFunction::Run() { brave_sync::SyncDebug::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnSyncDebug( + sync_service->GetBraveSyncClient()->sync_message_handler()->OnSyncDebug( params->message); return RespondNow(NoArguments()); @@ -77,9 +84,9 @@ ExtensionFunction::ResponseAction BraveSyncSaveInitDataFunction::Run() { brave_sync::SaveInitData::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnSaveInitData( + sync_service->GetBraveSyncClient()->sync_message_handler()->OnSaveInitData( params->seed ? *params->seed : std::vector(), params->device_id ? *params->device_id : std::vector()); @@ -87,9 +94,9 @@ ExtensionFunction::ResponseAction BraveSyncSaveInitDataFunction::Run() { } ExtensionFunction::ResponseAction BraveSyncSyncReadyFunction::Run() { - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnSyncReady(); + sync_service->GetBraveSyncClient()->sync_message_handler()->OnSyncReady(); return RespondNow(NoArguments()); } @@ -100,15 +107,16 @@ ExtensionFunction::ResponseAction BraveSyncGetExistingObjectsFunction::Run() { EXTENSION_FUNCTION_VALIDATE(params.get()); auto records = std::make_unique>(); - ::brave_sync::ConvertSyncRecords(params->records, *records.get()); + ::brave_sync::ConvertSyncRecords(params->records, records.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnGetExistingObjects( - params->category_name, - std::move(records), - base::Time::FromJsTime(params->last_record_timestamp), - params->is_truncated); + sync_service->GetBraveSyncClient() + ->sync_message_handler() + ->OnGetExistingObjects( + params->category_name, std::move(records), + base::Time::FromJsTime(params->last_record_timestamp), + params->is_truncated); return RespondNow(NoArguments()); } @@ -119,13 +127,13 @@ ExtensionFunction::ResponseAction BraveSyncResolvedSyncRecordsFunction::Run() { EXTENSION_FUNCTION_VALIDATE(params.get()); auto records = std::make_unique>(); - ::brave_sync::ConvertSyncRecords(params->records, *records.get()); + ::brave_sync::ConvertSyncRecords(params->records, records.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnResolvedSyncRecords( - params->category_name, - std::move(records)); + sync_service->GetBraveSyncClient() + ->sync_message_handler() + ->OnResolvedSyncRecords(params->category_name, std::move(records)); return RespondNow(NoArguments()); } @@ -136,23 +144,11 @@ BraveSyncSaveBookmarksBaseOrderFunction::Run() { brave_sync::SaveBookmarksBaseOrder::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); - DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler() - ->OnSaveBookmarksBaseOrder(params->order); - - return RespondNow(NoArguments()); -} - -ExtensionFunction::ResponseAction BraveSyncSaveBookmarkOrderFunction::Run() { - std::unique_ptr params( - brave_sync::SaveBookmarkOrder::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler()->OnSaveBookmarkOrder( - params->object_id, params->order); + sync_service->GetBraveSyncClient() + ->sync_message_handler() + ->OnSaveBookmarksBaseOrder(params->order); return RespondNow(NoArguments()); } @@ -162,19 +158,20 @@ ExtensionFunction::ResponseAction BraveSyncSyncWordsPreparedFunction::Run() { brave_sync::SyncWordsPrepared::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->sync_message_handler() - ->OnSyncWordsPrepared(params->words); + sync_service->GetBraveSyncClient() + ->sync_message_handler() + ->OnSyncWordsPrepared(params->words); return RespondNow(NoArguments()); } ExtensionFunction::ResponseAction BraveSyncExtensionInitializedFunction::Run() { // Also inform sync client extension started - BraveSyncService* sync_service = GetBraveSyncService(browser_context()); + BraveSyncService* sync_service = GetSyncService(browser_context()); DCHECK(sync_service); - sync_service->GetSyncClient()->OnExtensionInitialized(); + sync_service->GetBraveSyncClient()->OnExtensionInitialized(); return RespondNow(NoArguments()); } diff --git a/browser/extensions/api/brave_sync_api.h b/browser/extensions/api/brave_sync_api.h index 7c10e77808b8..7f7831dcc8df 100644 --- a/browser/extensions/api/brave_sync_api.h +++ b/browser/extensions/api/brave_sync_api.h @@ -60,12 +60,6 @@ class BraveSyncSaveBookmarksBaseOrderFunction ResponseAction Run() override; }; -class BraveSyncSaveBookmarkOrderFunction : public UIThreadExtensionFunction { - ~BraveSyncSaveBookmarkOrderFunction() override {} - DECLARE_EXTENSION_FUNCTION("braveSync.saveBookmarkOrder", UNKNOWN) - ResponseAction Run() override; -}; - class BraveSyncSyncWordsPreparedFunction : public UIThreadExtensionFunction { ~BraveSyncSyncWordsPreparedFunction() override {} DECLARE_EXTENSION_FUNCTION("braveSync.syncWordsPrepared", UNKNOWN) diff --git a/browser/extensions/api/brave_sync_event_router.cc b/browser/extensions/api/brave_sync_event_router.cc index f4ce1d3f3792..57582e37adfe 100644 --- a/browser/extensions/api/brave_sync_event_router.cc +++ b/browser/extensions/api/brave_sync_event_router.cc @@ -1,9 +1,13 @@ -/* 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 2019 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/browser/extensions/api/brave_sync_event_router.h" +#include +#include + #include "brave/common/extensions/api/brave_sync.h" #include "chrome/browser/profiles/profile.h" #include "extensions/browser/extension_event_histogram_value.h" @@ -142,13 +146,4 @@ void BraveSyncEventRouter::LoadClient() { event_router_->BroadcastEvent(std::move(event)); } -void BraveSyncEventRouter::ClearOrderMap() { - auto args = std::make_unique(); - std::unique_ptr event( - new Event(extensions::events::FOR_TEST, - extensions::api::brave_sync::OnClearOrderMap::kEventName, - std::move(args))); - event_router_->BroadcastEvent(std::move(event)); -} - -} // namespace extensions +} // namespace extensions diff --git a/browser/extensions/api/brave_sync_event_router.h b/browser/extensions/api/brave_sync_event_router.h index eac52983442b..7ad61e285d26 100644 --- a/browser/extensions/api/brave_sync_event_router.h +++ b/browser/extensions/api/brave_sync_event_router.h @@ -1,11 +1,13 @@ -/* 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 2019 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/. */ #ifndef BRAVE_BROWSER_EXTENSIONS_API_BRAVE_SYNC_EVENT_ROUTER_H_ #define BRAVE_BROWSER_EXTENSIONS_API_BRAVE_SYNC_EVENT_ROUTER_H_ #include +#include #include "extensions/browser/event_router.h" class Profile; @@ -16,9 +18,9 @@ namespace brave_sync { struct SyncRecord; struct Config; struct RecordAndExistingObject; -} // namespace brave_sync -} // namespace api -} // namespace extensions +} // namespace brave_sync +} // namespace api +} // namespace extensions using extensions::api::brave_sync::RecordAndExistingObject; @@ -30,7 +32,7 @@ namespace extensions { class BraveSyncEventRouter { public: - BraveSyncEventRouter(Profile* profile); + explicit BraveSyncEventRouter(Profile* profile); ~BraveSyncEventRouter(); void GotInitData( @@ -57,14 +59,12 @@ class BraveSyncEventRouter { void NeedSyncWords(const std::string& seed); - void ClearOrderMap(); - void LoadClient(); -private: + private: EventRouter* event_router_; }; -} // namespace extensions +} // namespace extensions -#endif // BRAVE_BROWSER_EXTENSIONS_API_BRAVE_SYNC_EVENT_ROUTER_H_ +#endif // BRAVE_BROWSER_EXTENSIONS_API_BRAVE_SYNC_EVENT_ROUTER_H_ diff --git a/browser/extensions/brave_component_extension_resource_manager.cc b/browser/extensions/brave_component_extension_resource_manager.cc index ce3c61f4fda7..a034b38ca85d 100644 --- a/browser/extensions/brave_component_extension_resource_manager.cc +++ b/browser/extensions/brave_component_extension_resource_manager.cc @@ -8,16 +8,20 @@ #include "brave/components/brave_extension/grit/brave_extension_generated_map.h" #include "brave/components/brave_extension/grit/brave_extension_resources_map.h" #include "brave/components/brave_rewards/browser/buildflags/buildflags.h" -#include "brave/components/brave_sync/grit/brave_sync_generated_map.h" -#include "brave/components/brave_sync/grit/brave_sync_resources_map.h" -#include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources_map.h" +#include "brave/components/brave_sync/buildflags/buildflags.h" #include "brave/components/brave_webtorrent/grit/brave_webtorrent_generated_map.h" +#include "brave/components/brave_webtorrent/grit/brave_webtorrent_resources_map.h" #if BUILDFLAG(BRAVE_REWARDS_ENABLED) #include "brave/components/brave_rewards/resources/extension/grit/brave_rewards_extension_resources_map.h" #include "brave/components/brave_rewards/resources/extension/grit/brave_rewards_panel_generated_map.h" #endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#include "brave/components/brave_sync/grit/brave_sync_generated_map.h" +#include "brave/components/brave_sync/grit/brave_sync_resources_map.h" +#endif + namespace extensions { BraveComponentExtensionResourceManager:: @@ -38,6 +42,7 @@ BraveComponentExtensionResourceManager() { kBraveRewardsPanelGenerated, kBraveRewardsPanelGeneratedSize); #endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) AddComponentResourceEntries( kBraveSyncResources, kBraveSyncResourcesSize); @@ -45,6 +50,7 @@ BraveComponentExtensionResourceManager() { AddComponentResourceEntries( kBraveSyncGenerated, kBraveSyncGeneratedSize); +#endif AddComponentResourceEntries( kBraveWebtorrentResources, diff --git a/browser/profiles/BUILD.gn b/browser/profiles/BUILD.gn index 119b5e5efa73..32a82129ed5c 100644 --- a/browser/profiles/BUILD.gn +++ b/browser/profiles/BUILD.gn @@ -7,16 +7,15 @@ source_set("profiles") { ] deps = [ "//base", - "//chrome/common", - "//content/public/common", "//brave/browser/tor", "//brave/browser/translate/buildflags", - "//brave/content:browser", "//brave/common/tor", "//brave/components/brave_ads/browser", - "//brave/components/brave_sync", "//brave/components/brave_rewards/browser", + "//brave/content:browser", + "//chrome/common", "//components/translate/core/browser", + "//content/public/common", "//ui/base", ] } diff --git a/browser/profiles/brave_profile_manager.cc b/browser/profiles/brave_profile_manager.cc index dee995cc3ae8..4d1be8ab7fdc 100644 --- a/browser/profiles/brave_profile_manager.cc +++ b/browser/profiles/brave_profile_manager.cc @@ -22,7 +22,6 @@ #include "brave/components/brave_rewards/browser/rewards_service_factory.h" #include "brave/components/brave_shields/browser/ad_block_regional_service.h" #include "brave/components/brave_shields/browser/ad_block_service.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" #include "brave/content/browser/webui/brave_shared_resources_data_source.h" #include "chrome/browser/browser_process.h" #include "chrome/common/chrome_constants.h" @@ -99,9 +98,6 @@ std::string BraveProfileManager::GetLastUsedProfileName() { void BraveProfileManager::DoFinalInitForServices(Profile* profile, bool go_off_the_record) { ProfileManager::DoFinalInitForServices(profile, go_off_the_record); - // BraveSyncService need to be created when profile initialized, otherwise - // it will only be constructed only when we open chrome:/sync/ - brave_sync::BraveSyncServiceFactory::GetForProfile(profile); brave_ads::AdsServiceFactory::GetForProfile(profile); brave_rewards::RewardsServiceFactory::GetForProfile(profile); content::URLDataSource::Add(profile, diff --git a/browser/profiles/tor_unittest_profile_manager.cc b/browser/profiles/tor_unittest_profile_manager.cc index 25fee9831d9b..059a2b53b571 100644 --- a/browser/profiles/tor_unittest_profile_manager.cc +++ b/browser/profiles/tor_unittest_profile_manager.cc @@ -12,8 +12,6 @@ #include "base/threading/thread_task_runner_handle.h" #include "brave/browser/profiles/brave_profile_manager.h" #include "brave/browser/tor/tor_profile_service.h" -#include "brave/components/brave_webtorrent/browser/buildflags/buildflags.h" -#include "brave/components/brave_webtorrent/browser/webtorrent_util.h" #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/test/base/testing_profile.h" @@ -63,9 +61,6 @@ Profile* TorUnittestProfileManager::CreateTorProfile( factory.CreateSyncable(registry.get())); RegisterUserProfilePrefs(registry.get()); tor::TorProfileService::RegisterProfilePrefs(registry.get()); -#if BUILDFLAG(ENABLE_BRAVE_WEBTORRENT) - webtorrent::RegisterProfilePrefs(registry.get()); -#endif profile_builder.SetPrefService(std::move(prefs)); profile_builder.SetPath(path); profile_builder.SetDelegate(delegate); diff --git a/browser/ui/BUILD.gn b/browser/ui/BUILD.gn index 74a341e85178..0337c4283a87 100644 --- a/browser/ui/BUILD.gn +++ b/browser/ui/BUILD.gn @@ -1,8 +1,9 @@ import("//brave/build/config.gni") -import("//build/config/features.gni") import("//brave/browser/translate/buildflags/buildflags.gni") import("//brave/components/brave_rewards/browser/buildflags/buildflags.gni") +import("//brave/components/brave_sync/buildflags/buildflags.gni") import("//brave/components/brave_wallet/browser/buildflags/buildflags.gni") +import("//build/config/features.gni") import("//chrome/common/features.gni") source_set("ui") { @@ -19,10 +20,15 @@ source_set("ui") { "webui/brave_web_ui_controller_factory.h", "webui/brave_webui_source.cc", "webui/brave_webui_source.h", - "webui/sync/sync_ui.cc", - "webui/sync/sync_ui.h", ] + if (enable_brave_sync) { + sources += [ + "webui/sync/sync_ui.cc", + "webui/sync/sync_ui.h", + ] + } + if (!is_android) { sources += [ "brave_browser_command_controller.cc", @@ -59,8 +65,8 @@ source_set("ui") { if (enable_sparkle) { sources += [ - "webui/settings/brave_relaunch_handler_mac.mm", "webui/settings/brave_relaunch_handler_mac.h", + "webui/settings/brave_relaunch_handler_mac.mm", ] } } @@ -83,8 +89,8 @@ source_set("ui") { if (enable_sparkle) { sources += [ - "views/update_recommended_message_box_mac.mm", "views/update_recommended_message_box_mac.h", + "views/update_recommended_message_box_mac.mm", ] } @@ -123,22 +129,19 @@ source_set("ui") { deps = [ "//base", "//brave/app:command_ids", - "//brave/app/theme:brave_unscaled_resources", "//brave/app/theme:brave_theme_resources", + "//brave/app/theme:brave_unscaled_resources", "//brave/app/vector_icons:vector_icons", + "//brave/browser:sparkle_buildflags", + "//brave/browser/devtools", + "//brave/browser/resources/settings:resources", + "//brave/browser/tor", "//brave/common", "//brave/components/brave_adblock_ui:generated_resources", "//brave/components/brave_new_tab_ui:generated_resources", "//brave/components/brave_rewards/browser", "//brave/components/brave_rewards/resources", - "//brave/components/brave_sync", - "//brave/components/brave_sync:static_resources", - "//brave/components/brave_sync:generated_resources", "//brave/components/brave_welcome_ui:generated_resources", - "//brave/browser:sparkle_buildflags", - "//brave/browser/devtools", - "//brave/browser/tor", - "//brave/browser/resources/settings:resources", "//chrome/app:command_ids", "//chrome/common", "//components/prefs", @@ -147,16 +150,22 @@ source_set("ui") { "//skia", "//ui/accessibility", "//ui/base", - "//ui/resources", "//ui/gfx", + "//ui/resources", ] - if (!is_android) { + if (enable_brave_sync) { deps += [ - "//brave/app:brave_generated_resources_grit", + "//brave/components/brave_sync", + "//brave/components/brave_sync:generated_resources", + "//brave/components/brave_sync:static_resources", ] } + if (!is_android) { + deps += [ "//brave/app:brave_generated_resources_grit" ] + } + if (enable_extensions) { sources += [ "brave_actions/brave_action_icon_with_badge_image_source.cc", @@ -187,8 +196,8 @@ source_set("ui") { deps += [ "//brave/browser/resources/extensions:resources", - "//brave/components/brave_extension:static_resources", "//brave/components/brave_extension:generated_resources", + "//brave/components/brave_extension:static_resources", "//chrome/browser/extensions", "//extensions/browser", ] @@ -204,14 +213,14 @@ source_set("ui") { if (brave_rewards_enabled) { sources += [ - "webui/brave_tip_ui.cc", - "webui/brave_tip_ui.h", - "webui/brave_rewards_source.cc", - "webui/brave_rewards_source.h", "webui/brave_rewards_internals_ui.cc", "webui/brave_rewards_internals_ui.h", + "webui/brave_rewards_source.cc", + "webui/brave_rewards_source.h", "webui/brave_rewards_ui.cc", "webui/brave_rewards_ui.h", + "webui/brave_tip_ui.cc", + "webui/brave_tip_ui.h", ] deps += [ @@ -225,8 +234,6 @@ source_set("ui") { "webui/brave_wallet_ui.cc", "webui/brave_wallet_ui.h", ] - deps += [ - "//brave/components/brave_wallet_ui:generated_resources", - ] + deps += [ "//brave/components/brave_wallet_ui:generated_resources" ] } } diff --git a/browser/ui/brave_browser_command_controller.cc b/browser/ui/brave_browser_command_controller.cc index ffccdbac69fb..82dff7bfb106 100644 --- a/browser/ui/brave_browser_command_controller.cc +++ b/browser/ui/brave_browser_command_controller.cc @@ -8,10 +8,11 @@ #include "brave/app/brave_command_ids.h" #include "brave/browser/tor/buildflags.h" #include "brave/browser/ui/brave_pages.h" +#include "brave/browser/ui/browser_commands.h" +#include "brave/common/brave_switches.h" #include "brave/components/brave_rewards/browser/buildflags/buildflags.h" +#include "brave/components/brave_sync/buildflags/buildflags.h" #include "brave/components/brave_wallet/browser/buildflags/buildflags.h" -#include "brave/components/brave_sync/brave_sync_service.h" -#include "brave/browser/ui/browser_commands.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -90,8 +91,10 @@ void BraveBrowserCommandController::InitBraveCommandState() { #if BUILDFLAG(BRAVE_WALLET_ENABLED) UpdateCommandForBraveWallet(); #endif - if (brave_sync::BraveSyncService::is_enabled()) +#if BUILDFLAG(ENABLE_BRAVE_SYNC) + if (switches::IsBraveSyncAllowedByFlag()) UpdateCommandForBraveSync(); +#endif } UpdateCommandForBraveAdblock(); #if BUILDFLAG(ENABLE_TOR) diff --git a/browser/ui/toolbar/brave_app_menu_model.cc b/browser/ui/toolbar/brave_app_menu_model.cc index 2c0420773a2e..1664fb33b6b7 100644 --- a/browser/ui/toolbar/brave_app_menu_model.cc +++ b/browser/ui/toolbar/brave_app_menu_model.cc @@ -7,7 +7,6 @@ #include "brave/app/brave_command_ids.h" #include "brave/browser/profiles/profile_util.h" -#include "brave/components/brave_sync/brave_sync_service.h" #include "brave/grit/brave_generated_resources.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/profiles/profile.h" @@ -37,22 +36,17 @@ void BraveAppMenuModel::InsertBraveMenuItems() { GetIndexOfCommandId(IDC_SHOW_DOWNLOADS), IDC_SHOW_BRAVE_REWARDS, IDS_SHOW_BRAVE_REWARDS); - #if BUILDFLAG(BRAVE_WALLET_ENABLED) - InsertItemWithStringIdAt( - GetIndexOfCommandId(IDC_SHOW_BRAVE_REWARDS), - IDC_SHOW_BRAVE_WALLET, - IDS_SHOW_BRAVE_WALLET); - #endif - if (brave_sync::BraveSyncService::is_enabled()) { - InsertItemWithStringIdAt( - #if BUILDFLAG(BRAVE_WALLET_ENABLED) - GetIndexOfCommandId(IDC_SHOW_BRAVE_WALLET), - #else - GetIndexOfCommandId(IDC_SHOW_BRAVE_REWARDS), - #endif - IDC_SHOW_BRAVE_SYNC, - IDS_SHOW_BRAVE_SYNC); - } +#if BUILDFLAG(BRAVE_WALLET_ENABLED) + InsertItemWithStringIdAt(GetIndexOfCommandId(IDC_SHOW_BRAVE_REWARDS), + IDC_SHOW_BRAVE_WALLET, IDS_SHOW_BRAVE_WALLET); +#endif + InsertItemWithStringIdAt( +#if BUILDFLAG(BRAVE_WALLET_ENABLED) + GetIndexOfCommandId(IDC_SHOW_BRAVE_WALLET), +#else + GetIndexOfCommandId(IDC_SHOW_BRAVE_REWARDS), +#endif + IDC_SHOW_BRAVE_SYNC, IDS_SHOW_BRAVE_SYNC); } InsertItemWithStringIdAt( GetIndexOfCommandId(IDC_SHOW_DOWNLOADS), diff --git a/browser/ui/toolbar/brave_app_menu_model_browsertest.cc b/browser/ui/toolbar/brave_app_menu_model_browsertest.cc index 4d37166dbd7b..fd0a6b06bf5b 100644 --- a/browser/ui/toolbar/brave_app_menu_model_browsertest.cc +++ b/browser/ui/toolbar/brave_app_menu_model_browsertest.cc @@ -9,6 +9,9 @@ #include "brave/app/brave_command_ids.h" #include "brave/browser/ui/brave_browser_command_controller.h" +#include "brave/components/brave_rewards/browser/buildflags/buildflags.h" +#include "brave/components/brave_sync/buildflags/buildflags.h" +#include "brave/components/brave_wallet/browser/buildflags/buildflags.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_window.h" @@ -18,8 +21,6 @@ #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" -#include "brave/components/brave_rewards/browser/buildflags/buildflags.h" -#include "brave/components/brave_wallet/browser/buildflags/buildflags.h" using BraveAppMenuBrowserTest = InProcessBrowserTest; @@ -32,26 +33,30 @@ IN_PROC_BROWSER_TEST_F(BraveAppMenuBrowserTest, BasicTest) { // -1 means |model| doesn't have passed command id. EXPECT_NE(-1, normal_model.GetIndexOfCommandId(IDC_SHOW_BRAVE_REWARDS)); EXPECT_NE(-1, normal_model.GetIndexOfCommandId(IDC_SHOW_BRAVE_SYNC)); - #if BUILDFLAG(BRAVE_WALLET_ENABLED) +#if BUILDFLAG(BRAVE_WALLET_ENABLED) EXPECT_NE(-1, normal_model.GetIndexOfCommandId(IDC_SHOW_BRAVE_WALLET)); - #else +#else EXPECT_EQ(-1, normal_model.GetIndexOfCommandId(IDC_SHOW_BRAVE_WALLET)); - #endif +#endif auto* command_controller = browser()->command_controller(); - #if BUILDFLAG(BRAVE_REWARDS_ENABLED) +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_REWARDS)); - #else +#else EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_REWARDS)); - #endif +#endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_SYNC)); +#else + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_SYNC)); +#endif - #if BUILDFLAG(BRAVE_WALLET_ENABLED) +#if BUILDFLAG(BRAVE_WALLET_ENABLED) EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_WALLET)); - #else +#else EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_WALLET)); - #endif +#endif // Create proviate browser. auto* private_browser = CreateIncognitoBrowser(); @@ -67,12 +72,16 @@ IN_PROC_BROWSER_TEST_F(BraveAppMenuBrowserTest, BasicTest) { EXPECT_NE(-1, private_model.GetIndexOfCommandId(IDC_SHOW_BRAVE_SYNC)); command_controller = private_browser->command_controller(); - #if BUILDFLAG(BRAVE_REWARDS_ENABLED) +#if BUILDFLAG(BRAVE_REWARDS_ENABLED) EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_REWARDS)); - #else +#else EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_REWARDS)); - #endif +#endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) EXPECT_TRUE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_SYNC)); +#else + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_SHOW_BRAVE_SYNC)); +#endif content::WindowedNotificationObserver browser_creation_observer( chrome::NOTIFICATION_BROWSER_OPENED, diff --git a/browser/ui/webui/brave_web_ui_controller_factory.cc b/browser/ui/webui/brave_web_ui_controller_factory.cc index 092780e58dc5..37e80ea9c8ad 100644 --- a/browser/ui/webui/brave_web_ui_controller_factory.cc +++ b/browser/ui/webui/brave_web_ui_controller_factory.cc @@ -10,11 +10,11 @@ #include "base/memory/ptr_util.h" #include "brave/browser/ui/webui/brave_adblock_ui.h" #include "brave/browser/ui/webui/brave_new_tab_ui.h" -#include "brave/browser/ui/webui/sync/sync_ui.h" +#include "brave/common/brave_switches.h" #include "brave/common/webui_url_constants.h" #include "brave/components/brave_rewards/browser/buildflags/buildflags.h" +#include "brave/components/brave_sync/buildflags/buildflags.h" #include "brave/components/brave_wallet/browser/buildflags/buildflags.h" -#include "brave/components/brave_sync/brave_sync_service.h" #include "chrome/common/url_constants.h" #include "url/gurl.h" @@ -33,6 +33,10 @@ #include "brave/browser/ui/webui/brave_wallet_ui.h" #endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#include "brave/browser/ui/webui/sync/sync_ui.h" +#endif + using content::WebUI; using content::WebUIController; @@ -52,14 +56,16 @@ WebUIController* NewWebUI(WebUI* web_ui, const GURL& url) { template<> WebUIController* NewWebUI(WebUI* web_ui, const GURL& url) { auto host = url.host_piece(); - if (host == kBraveUISyncHost && brave_sync::BraveSyncService::is_enabled()) { - return new SyncUI(web_ui, url.host()); - } else if (host == kAdblockHost) { + if (host == kAdblockHost) { return new BraveAdblockUI(web_ui, url.host()); #if BUILDFLAG(BRAVE_WALLET_ENABLED) } else if (host == kWalletHost) { return new BraveWalletUI(web_ui, url.host()); #endif +#if BUILDFLAG(ENABLE_BRAVE_SYNC) + } else if (host == kBraveUISyncHost && switches::IsBraveSyncAllowedByFlag()) { + return new SyncUI(web_ui, url.host()); +#endif #if BUILDFLAG(BRAVE_REWARDS_ENABLED) } else if (host == kRewardsHost) { return new BraveRewardsUI(web_ui, url.host()); @@ -98,8 +104,10 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui, #endif url.host_piece() == kWelcomeHost || url.host_piece() == chrome::kChromeUIWelcomeURL || +#if BUILDFLAG(ENABLE_BRAVE_SYNC) (url.host_piece() == kBraveUISyncHost && - brave_sync::BraveSyncService::is_enabled()) || + switches::IsBraveSyncAllowedByFlag()) || +#endif url.host_piece() == chrome::kChromeUINewTabHost || url.host_piece() == chrome::kChromeUISettingsHost) { return &NewWebUI; diff --git a/browser/ui/webui/sync/sync_ui.cc b/browser/ui/webui/sync/sync_ui.cc index 16b98c6a67c2..71022a4d0181 100644 --- a/browser/ui/webui/sync/sync_ui.cc +++ b/browser/ui/webui/sync/sync_ui.cc @@ -1,20 +1,26 @@ -/* 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 2019 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/browser/ui/webui/sync/sync_ui.h" +#include +#include + #include "base/bind.h" #include "base/memory/weak_ptr.h" #include "brave/common/webui_url_constants.h" #include "brave/components/brave_sync/brave_sync_service.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" #include "brave/components/brave_sync/brave_sync_service_observer.h" -#include "brave/components/brave_sync/grit/brave_sync_resources.h" #include "brave/components/brave_sync/grit/brave_sync_generated_map.h" -#include "brave/components/brave_sync/sync_devices.h" +#include "brave/components/brave_sync/grit/brave_sync_resources.h" +#include "brave/components/brave_sync/public/brave_profile_sync_service.h" #include "brave/components/brave_sync/settings.h" +#include "brave/components/brave_sync/sync_devices.h" #include "brave/components/brave_sync/values_conv.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui_message_handler.h" @@ -60,7 +66,7 @@ class SyncUIDOMHandler : public WebUIMessageHandler, std::unique_ptr settings, std::unique_ptr devices); - brave_sync::BraveSyncService *sync_service_ = nullptr; // NOT OWNED + brave_sync::BraveSyncService* sync_service_ = nullptr; // NOT OWNED base::WeakPtrFactory weak_ptr_factory_; @@ -118,7 +124,12 @@ void SyncUIDOMHandler::RegisterMessages() { void SyncUIDOMHandler::Init() { Profile* profile = Profile::FromWebUI(web_ui()); - sync_service_ = brave_sync::BraveSyncServiceFactory::GetForProfile(profile); + auto* profile_sync_service = + static_cast( + ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile( + profile)); + + sync_service_ = profile_sync_service->GetSyncService(); if (sync_service_) sync_service_->AddObserver(this); } @@ -244,7 +255,7 @@ void SyncUIDOMHandler::OnHaveSyncWords( "sync_ui_exports.haveSyncWords", base::Value(sync_words)); } -} // namespace +} // namespace SyncUI::SyncUI(content::WebUI* web_ui, const std::string& name) : BasicUI(web_ui, name, diff --git a/browser/widevine/brave_widevine_bundle_manager_unittest.cc b/browser/widevine/brave_widevine_bundle_manager_unittest.cc index 98784c42ca7c..4bedd01ecf0e 100644 --- a/browser/widevine/brave_widevine_bundle_manager_unittest.cc +++ b/browser/widevine/brave_widevine_bundle_manager_unittest.cc @@ -14,7 +14,6 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" -#include "components/pref_registry/pref_registry_syncable.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/cdm_registry.h" #include "content/public/common/cdm_info.h" @@ -73,15 +72,7 @@ class BraveWidevineBundleManagerTest : public testing::Test { content::CdmRegistry::GetInstance()->Init(); } - void PreparePrefs() { - auto* registry = static_cast( - pref_service()->DeprecatedGetPrefRegistry()); - registry->RegisterBooleanPref(kWidevineOptedIn, false); - BraveWidevineBundleManager::RegisterProfilePrefs(registry); - } - void PrepareTest(bool empty_cdms) { - PreparePrefs(); PrepareCdmRegistry(empty_cdms); } diff --git a/chromium_src/chrome/browser/bookmarks/bookmark_model_factory.cc b/chromium_src/chrome/browser/bookmarks/bookmark_model_factory.cc deleted file mode 100644 index a3cc1bfedc6f..000000000000 --- a/chromium_src/chrome/browser/bookmarks/bookmark_model_factory.cc +++ /dev/null @@ -1,4 +0,0 @@ -#include "chrome/browser/bookmarks/chrome_bookmark_client.h" -#include "brave/browser/bookmarks/brave_bookmark_client.h" -#define ChromeBookmarkClient BraveBookmarkClient -#include "../../../../../../chrome/browser/bookmarks/bookmark_model_factory.cc" diff --git a/chromium_src/chrome/browser/prefs/browser_prefs.cc b/chromium_src/chrome/browser/prefs/browser_prefs.cc index 1e3f1a8d1269..d8b472bcc2e9 100644 --- a/chromium_src/chrome/browser/prefs/browser_prefs.cc +++ b/chromium_src/chrome/browser/prefs/browser_prefs.cc @@ -1,2 +1,8 @@ +/* Copyright (c) 2019 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/browser/brave_profile_prefs.h" #include "brave/browser/brave_local_state_prefs.h" #include "../../../../chrome/browser/prefs/browser_prefs.cc" diff --git a/chromium_src/chrome/browser/profiles/pref_service_builder_utils.cc b/chromium_src/chrome/browser/profiles/pref_service_builder_utils.cc new file mode 100644 index 000000000000..b4ffd6dd94c0 --- /dev/null +++ b/chromium_src/chrome/browser/profiles/pref_service_builder_utils.cc @@ -0,0 +1,55 @@ +/* Copyright (c) 2019 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 "chrome/browser/profiles/pref_service_builder_utils.h" + +#define RegisterProfilePrefs RegisterProfilePrefs_ChromiumImpl +#include "../../../../../chrome/browser/profiles/pref_service_builder_utils.cc" +#undef RegisterProfilePrefs + +#include "brave/browser/brave_profile_prefs.h" +#include "brave/browser/themes/brave_theme_service.h" +#include "brave/browser/tor/buildflags.h" +#include "brave/common/pref_names.h" +#include "brave/components/brave_rewards/browser/rewards_service.h" +#include "chrome/common/pref_names.h" +#include "components/spellcheck/browser/pref_names.h" + +#if BUILDFLAG(ENABLE_TOR) +#include "brave/browser/tor/tor_profile_service.h" +#endif + +// Prefs for KeyedService +void RegisterProfilePrefs(bool is_signin_profile, + const std::string& locale, + user_prefs::PrefRegistrySyncable* registry) { + RegisterProfilePrefs_ChromiumImpl(is_signin_profile, locale, registry); + + // appearance +#if !defined(OS_ANDROID) + BraveThemeService::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_TOR) + tor::TorProfileService::RegisterProfilePrefs(registry); +#endif + + brave_rewards::RewardsService::RegisterProfilePrefs(registry); + + // Disable spell check service + registry->SetDefaultPrefValue( + spellcheck::prefs::kSpellCheckUseSpellingService, base::Value(false)); + + // Make sure sign into Brave is not enabled + // The older kSigninAllowed is deprecated and only in use in Android until + // C71. + registry->SetDefaultPrefValue(prefs::kSigninAllowedOnNextStartup, + base::Value(false)); + +#if defined(OS_LINUX) + // Use brave theme by default instead of gtk theme. + registry->SetDefaultPrefValue(prefs::kUsesSystemTheme, base::Value(false)); +#endif +} diff --git a/chromium_src/chrome/browser/sync/profile_sync_service_factory.cc b/chromium_src/chrome/browser/sync/profile_sync_service_factory.cc new file mode 100644 index 000000000000..3c5a62c9e770 --- /dev/null +++ b/chromium_src/chrome/browser/sync/profile_sync_service_factory.cc @@ -0,0 +1,31 @@ +/* Copyright (c) 2019 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 "components/sync/driver/profile_sync_service.h" +#include "brave/components/brave_sync/buildflags/buildflags.h" + +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#include "brave/components/brave_sync/brave_profile_sync_service_impl.h" +using brave_sync::BraveProfileSyncServiceImpl; +#endif + +class Profile; + +namespace { + +std::unique_ptr BraveBuildServiceInstanceFor( + Profile* profile, + syncer::ProfileSyncService::InitParams init_params) { +#if BUILDFLAG(ENABLE_BRAVE_SYNC) + return std::make_unique(profile, + std::move(init_params)); +#else + return std::make_unique(std::move(init_params)); +#endif +} + +} // namespace + +#include "../../../../../chrome/browser/sync/profile_sync_service_factory.cc" // NOLINT diff --git a/chromium_src/chrome/browser/ui/autofill/payments/brave_save_card_bubble_controller_impl_browsertest.cc b/chromium_src/chrome/browser/ui/autofill/payments/brave_save_card_bubble_controller_impl_browsertest.cc index 14352c1eca23..e541c493187c 100644 --- a/chromium_src/chrome/browser/ui/autofill/payments/brave_save_card_bubble_controller_impl_browsertest.cc +++ b/chromium_src/chrome/browser/ui/autofill/payments/brave_save_card_bubble_controller_impl_browsertest.cc @@ -5,11 +5,15 @@ #include #include "base/macros.h" +#include "brave/components/brave_sync/brave_sync_prefs.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/pref_service.h" +#include "components/sync/base/sync_prefs.h" #include "testing/gtest/include/gtest/gtest.h" class BraveSaveCardBubbleControllerImplTest : public InProcessBrowserTest { @@ -28,6 +32,19 @@ class BraveSaveCardBubbleControllerImplTest : public InProcessBrowserTest { controller_->ShowBubbleForSignInPromo(); } + void EnableBraveSync(PrefService* pref) { + pref->SetBoolean(brave_sync::prefs::kSyncEnabled, true); + syncer::SyncPrefs sync_prefs(pref); + sync_prefs.SetSyncRequested(true); + pref->SetInteger(brave_sync::prefs::kSyncMigrateBookmarksVersion, 2); + } + + void DisableBraveSync(PrefService* pref) { + pref->SetBoolean(brave_sync::prefs::kSyncEnabled, false); + syncer::SyncPrefs sync_prefs(pref); + sync_prefs.SetSyncRequested(false); + } + autofill::SaveCardBubbleControllerImpl* controller() { return controller_; } private: @@ -38,7 +55,18 @@ class BraveSaveCardBubbleControllerImplTest : public InProcessBrowserTest { // Tests that requesting to open signin promo bubble doesn't result in the // bubble being shown. -IN_PROC_BROWSER_TEST_F(BraveSaveCardBubbleControllerImplTest, NoSignInPromo) { +IN_PROC_BROWSER_TEST_F(BraveSaveCardBubbleControllerImplTest, + NoSignInPromoBraveSyncDisabled) { + ShowUi(); + EXPECT_EQ(nullptr, controller()->save_card_bubble_view()); +} + +IN_PROC_BROWSER_TEST_F(BraveSaveCardBubbleControllerImplTest, + NoSignInPromoBraveSyncEnabled) { + EnableBraveSync(browser()->profile()->GetPrefs()); + ShowUi(); + EXPECT_EQ(nullptr, controller()->save_card_bubble_view()); + DisableBraveSync(browser()->profile()->GetPrefs()); ShowUi(); EXPECT_EQ(nullptr, controller()->save_card_bubble_view()); } diff --git a/chromium_src/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chromium_src/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc index e5fbd0978788..bf80b25023a3 100644 --- a/chromium_src/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc +++ b/chromium_src/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc @@ -3,10 +3,11 @@ * 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 "../../../../../../../chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" - -#define BRAVE_SHOULD_SHOW_SIGNIN_PROMO_SHORT_CIRCUIT_TO_FALSE \ -return false; +#define CHECK_SYNC_POLICY \ + if (sync_service && sync_service->HasDisableReason( \ + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)) \ + return false; #include "../../../../../../../chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc" // NOLINT -#undef BRAVE_SHOULD_SHOW_SIGNIN_PROMO_SHORT_CIRCUIT_TO_FALSE +#undef CHECK_SYNC_POLICY + diff --git a/chromium_src/chrome/common/pref_names.h b/chromium_src/chrome/common/pref_names.h index ecf039226c5c..8b12f1a2f1ac 100644 --- a/chromium_src/chrome/common/pref_names.h +++ b/chromium_src/chrome/common/pref_names.h @@ -1,4 +1,12 @@ -#include "../../../chrome/common/pref_names.h" +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_CHROME_COMMON_PREF_NAMES_H_ +#define BRAVE_CHROMIUM_SRC_CHROME_COMMON_PREF_NAMES_H_ + +#include "../../../../chrome/common/pref_names.h" namespace prefs { @@ -8,3 +16,5 @@ extern const char kImportDialogLedger[]; extern const char kImportDialogWindows[]; } // namespace prefs + +#endif // BRAVE_CHROMIUM_SRC_CHROME_COMMON_PREF_NAMES_H_ diff --git a/chromium_src/components/sync/driver/glue/sync_engine_backend.cc b/chromium_src/components/sync/driver/glue/sync_engine_backend.cc new file mode 100644 index 000000000000..3dd9346e6a27 --- /dev/null +++ b/chromium_src/components/sync/driver/glue/sync_engine_backend.cc @@ -0,0 +1,75 @@ +/* Copyright (c) 2019 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 + +#include "brave/components/brave_sync/buildflags/buildflags.h" +#include "components/sync/driver/glue/sync_engine_impl.h" +#include "components/sync/engine/sync_engine_host.h" + +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#include "base/memory/weak_ptr.h" +#include "brave/components/brave_sync/jslib_messages.h" +#include "brave/components/brave_sync/public/brave_profile_sync_service.h" + +using brave_sync::BraveProfileSyncService; +using brave_sync::GetRecordsCallback; +using brave_sync::RecordsList; +#endif + +namespace syncer { + +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +SyncEngineHost* BraveGetSyncEngineHost(SyncEngineImpl* sync_engine) { + return sync_engine->host_; +} + +void OnNudgeSyncCycleOnOwnerThread(base::WeakPtr sync_engine, + brave_sync::RecordsListPtr records_list) { + if (sync_engine.get()) + static_cast( + BraveGetSyncEngineHost(sync_engine.get())) + ->OnNudgeSyncCycle(std::move(records_list)); +} + +void OnNudgeSyncCycle(WeakHandle sync_engine_impl, + brave_sync::RecordsListPtr records_list) { + sync_engine_impl.Call(FROM_HERE, &OnNudgeSyncCycleOnOwnerThread, + base::Passed(&records_list)); +} + +void OnPollSyncCycleOnOwnerThread(base::WeakPtr sync_engine, + GetRecordsCallback cb, + base::WaitableEvent* wevent) { + if (sync_engine.get()) + static_cast( + BraveGetSyncEngineHost(sync_engine.get())) + ->OnPollSyncCycle(std::move(cb), wevent); +} + +void OnPollSyncCycle(WeakHandle sync_engine_impl, + GetRecordsCallback cb, + base::WaitableEvent* wevent) { + sync_engine_impl.Call(FROM_HERE, &OnPollSyncCycleOnOwnerThread, + base::Passed(&cb), wevent); +} +#endif + +void BraveInit(WeakHandle sync_engine_impl, + SyncManager::InitArgs* args) { +#if BUILDFLAG(ENABLE_BRAVE_SYNC) + DCHECK(args); + args->nudge_sync_cycle_delegate_function = + base::BindRepeating(&OnNudgeSyncCycle, sync_engine_impl); + args->poll_sync_cycle_delegate_function = + base::BindRepeating(&OnPollSyncCycle, sync_engine_impl); +#endif +} + +} // namespace syncer + +#define BRAVE_SYNC_ENGINE_BACKEND_DO_INITIALIZE BraveInit(host_, &args); + +#include "../../../../../../components/sync/driver/glue/sync_engine_backend.cc" // NOLINT diff --git a/chromium_src/components/sync/driver/glue/sync_engine_impl.h b/chromium_src/components/sync/driver/glue/sync_engine_impl.h new file mode 100644 index 000000000000..98a3c9aa9129 --- /dev/null +++ b/chromium_src/components/sync/driver/glue/sync_engine_impl.h @@ -0,0 +1,14 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_DRIVER_GLUE_SYNC_ENGINE_IMPL_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_DRIVER_GLUE_SYNC_ENGINE_IMPL_H_ + +#define BRAVE_SYNC_ENGINE_IMPL_H \ + friend SyncEngineHost* BraveGetSyncEngineHost(SyncEngineImpl*); + +#include "../../../../../../components/sync/driver/glue/sync_engine_impl.h" // NOLINT +#undef BRAVE_SYNC_ENGINE_IMPL_H +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_DRIVER_GLUE_SYNC_ENGINE_IMPL_H_ diff --git a/chromium_src/components/sync/driver/profile_sync_service.cc b/chromium_src/components/sync/driver/profile_sync_service.cc new file mode 100644 index 000000000000..5b995a855e87 --- /dev/null +++ b/chromium_src/components/sync/driver/profile_sync_service.cc @@ -0,0 +1,81 @@ +/* Copyright (c) 2019 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/chromium_src/components/sync/driver/profile_sync_service.h" + +#include + +#include "brave/components/brave_sync/buildflags/buildflags.h" + +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "brave/components/brave_sync/jslib_messages.h" +#include "brave/components/brave_sync/public/brave_profile_sync_service.h" +#include "chrome/browser/sync/chrome_sync_client.h" +#include "content/public/browser/browser_thread.h" + +using brave_sync::BraveProfileSyncService; +#endif + +namespace syncer { + +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +const int64_t kBraveDefaultPollIntervalSeconds = 60; + +bool IsBraveSyncEnabled(ProfileSyncService* profile_sync_service) { + return static_cast(profile_sync_service) + ->IsBraveSyncEnabled(); +} + +void OnNudgeSyncCycle(base::WeakPtr profile_sync_service, + brave_sync::RecordsListPtr records_list) { + if (profile_sync_service.get()) { + static_cast(profile_sync_service.get()) + ->OnNudgeSyncCycle(std::move(records_list)); + } +} + +void OnPollSyncCycle(base::WeakPtr profile_sync_service, + brave_sync::GetRecordsCallback cb, + base::WaitableEvent* wevent) { + if (profile_sync_service.get()) { + static_cast(profile_sync_service.get()) + ->OnPollSyncCycle(std::move(cb), wevent); + } +} +#endif + +void BraveInit(base::WeakPtr profile_sync_service, + SyncPrefs* sync_prefs, + syncer::SyncEngine::InitParams* params) { +#if BUILDFLAG(ENABLE_BRAVE_SYNC) + DCHECK(params); + params->nudge_sync_cycle_delegate_function = + base::BindRepeating(&OnNudgeSyncCycle, profile_sync_service); + params->poll_sync_cycle_delegate_function = + base::BindRepeating(&OnPollSyncCycle, profile_sync_service); + + sync_prefs->SetPollInterval( + base::TimeDelta::FromSeconds(syncer::kBraveDefaultPollIntervalSeconds)); +#endif +} + +} // namespace syncer + +// avoid redefining IsSyncFeatureEnabled in header +#include "components/sync/driver/sync_service.h" +// For use_transport_only_mode +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#define IsSyncFeatureEnabled() IsBraveSyncEnabled(this) +#endif +#define BRAVE_PROFILE_SYNC_SERVICE_START_UP_SLOW_ENGINE_COMPONENTS \ + BraveInit(sync_enabled_weak_factory_.GetWeakPtr(), &sync_prefs_, ¶ms); + +#include "../../../../components/sync/driver/profile_sync_service.cc" // NOLINT +#undef BRAVE_PROFILE_SYNC_SERVICE_START_UP_SLOW_ENGINE_COMPONENTS +#if BUILDFLAG(ENABLE_BRAVE_SYNC) +#undef IsSyncFeatureEnabled +#endif diff --git a/chromium_src/components/sync/driver/profile_sync_service.h b/chromium_src/components/sync/driver/profile_sync_service.h new file mode 100644 index 000000000000..e516f8872b60 --- /dev/null +++ b/chromium_src/components/sync/driver/profile_sync_service.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_DRIVER_PROFILE_SYNC_SERVICE_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_DRIVER_PROFILE_SYNC_SERVICE_H_ + +namespace brave_sync { +class BraveProfileSyncServiceImpl; +} // namespace brave_sync + +#define BRAVE_PROFILE_SYNC_SERVICE_H \ + friend class brave_sync::BraveProfileSyncServiceImpl; + +#include "../../../../../components/sync/driver/profile_sync_service.h" +#undef BRAVE_PROFILE_SYNC_SERVICE_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_DRIVER_PROFILE_SYNC_SERVICE_H_ diff --git a/chromium_src/components/sync/driver/sync_driver_switches.cc b/chromium_src/components/sync/driver/sync_driver_switches.cc new file mode 100644 index 000000000000..09f3e10dd165 --- /dev/null +++ b/chromium_src/components/sync/driver/sync_driver_switches.cc @@ -0,0 +1,18 @@ +/* Copyright (c) 2019 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/. */ + +#define IsSyncAllowedByFlag IsSyncAllowedByFlag_ChromiumImpl +#include "../../../../../components/sync/driver/sync_driver_switches.cc" // NOLINT +#undef IsSyncAllowedByFlag + +#include "brave/common/brave_switches.h" + +namespace switches { + +bool IsSyncAllowedByFlag() { + return IsSyncAllowedByFlag_ChromiumImpl() && IsBraveSyncAllowedByFlag(); +} + +} // namespace switches diff --git a/chromium_src/components/sync/engine/sync_engine.h b/chromium_src/components/sync/engine/sync_engine.h new file mode 100644 index 000000000000..2b27b9836498 --- /dev/null +++ b/chromium_src/components/sync/engine/sync_engine.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_SYNC_ENGINE_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_SYNC_ENGINE_H_ + +#include "brave/components/brave_sync/jslib_messages_fwd.h" + +#define BRAVE_SYNC_ENGINE_INIT_PARAMS_H \ + brave_sync::NudgeSyncCycleDelegate nudge_sync_cycle_delegate_function; \ + brave_sync::PollSyncCycleDelegate poll_sync_cycle_delegate_function; + +#include "../../../../../components/sync/engine/sync_engine.h" +#undef BRAVE_SYNC_ENGINE_INIT_PARAMS_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_SYNC_ENGINE_H_ diff --git a/chromium_src/components/sync/engine/sync_manager.h b/chromium_src/components/sync/engine/sync_manager.h new file mode 100644 index 000000000000..cd0a9e821e36 --- /dev/null +++ b/chromium_src/components/sync/engine/sync_manager.h @@ -0,0 +1,22 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_SYNC_MANAGER_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_SYNC_MANAGER_H_ + +#include "brave/components/brave_sync/jslib_messages_fwd.h" + +namespace syncer { +class Syncer; +} // namespace syncer + +#define BRAVE_SYNC_MANAGER_INIT_ARGS_H \ + brave_sync::NudgeSyncCycleDelegate nudge_sync_cycle_delegate_function; \ + brave_sync::PollSyncCycleDelegate poll_sync_cycle_delegate_function; + +#include "../../../../../components/sync/engine/sync_manager.h" +#undef BRAVE_SYNC_MANAGER_INIT_ARGS_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_SYNC_MANAGER_H_ diff --git a/chromium_src/components/sync/engine_impl/commit.cc b/chromium_src/components/sync/engine_impl/commit.cc new file mode 100644 index 000000000000..5c61637db9f2 --- /dev/null +++ b/chromium_src/components/sync/engine_impl/commit.cc @@ -0,0 +1,170 @@ +/* Copyright (c) 2019 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/. */ + +namespace sync_pb { +class ClientToServerMessage; +class ClientToServerResponse; +} // namespace sync_pb + +namespace syncer { +class SyncCycle; +class SyncerError; +namespace { + +SyncerError PostBraveCommit(sync_pb::ClientToServerMessage* message, + sync_pb::ClientToServerResponse* response, + SyncCycle* cycle); +} + +} // namespace syncer + +#define BRAVE_COMMIT_POST_AND_PROCESS_RESPONSE \ + PostBraveCommit(&message_, &response, cycle); + +#include "../../../../../components/sync/engine_impl/commit.cc" // NOLINT +#undef BRAVE_COMMIT_POST_AND_PROCESS_RESPONSE + +#include "base/base64.h" +#include "brave/components/brave_sync/jslib_const.h" +#include "brave/components/brave_sync/jslib_messages.h" +#include "brave/components/brave_sync/jslib_messages_fwd.h" +#include "components/sync/base/time.h" +#include "components/sync/base/unique_position.h" + +namespace syncer { +namespace { +using brave_sync::jslib::MetaInfo; +using brave_sync::jslib::SyncRecord; +const char kBookmarkBarTag[] = "bookmark_bar"; + +void CreateSuccessfulCommitResponse( + const sync_pb::SyncEntity& entity, + sync_pb::CommitResponse::EntryResponse* response, + const std::string& new_object_id) { + response->set_response_type(sync_pb::CommitResponse::SUCCESS); + response->set_non_unique_name(entity.name()); + response->set_version(entity.version() + 1); + response->set_parent_id_string(entity.parent_id_string()); + + if (new_object_id.empty()) + response->set_id_string(entity.id_string()); + else + response->set_id_string(new_object_id); +} + +brave_sync::RecordsListPtr ConvertCommitsToBraveRecords( + sync_pb::ClientToServerMessage* message, + sync_pb::ClientToServerResponse* response) { + brave_sync::RecordsListPtr record_list = + std::make_unique(); + const sync_pb::CommitMessage& commit_message = message->commit(); + const std::string cache_guid = commit_message.cache_guid(); + for (int i = 0; i < commit_message.entries_size(); ++i) { + sync_pb::SyncEntity entity = commit_message.entries(i); + std::string new_object_id; + if (entity.specifics().has_bookmark()) { + const sync_pb::BookmarkSpecifics& bm_specifics = + entity.specifics().bookmark(); + auto record = std::make_unique(); + record->objectData = brave_sync::jslib_const::SyncObjectData_BOOKMARK; + + auto bookmark = std::make_unique(); + bookmark->site.location = bm_specifics.url(); + bookmark->site.title = bm_specifics.title(); + bookmark->site.customTitle = bm_specifics.title(); + // bookmark->site.lastAccessedTime - ignored + bookmark->site.creationTime = + ProtoTimeToTime(bm_specifics.creation_time_us()); + bookmark->site.favicon = bm_specifics.icon_url(); + bookmark->isFolder = entity.folder(); + // only mattters for direct children of permanent nodes + bookmark->hideInToolbar = entity.parent_id_string() != kBookmarkBarTag; + + std::string originator_cache_guid; + std::string originator_client_item_id; + bool skip_record = false; + for (int i = 0; i < bm_specifics.meta_info_size(); ++i) { + if (bm_specifics.meta_info(i).key() == "order") { + bookmark->order = bm_specifics.meta_info(i).value(); + } else if (bm_specifics.meta_info(i).key() == "object_id") { + new_object_id = bm_specifics.meta_info(i).value(); + } else if (bm_specifics.meta_info(i).key() == "parent_object_id") { + bookmark->parentFolderObjectId = bm_specifics.meta_info(i).value(); + } else if (bm_specifics.meta_info(i).key() == "sync_timestamp") { + record->syncTimestamp = base::Time::FromJsTime( + std::stod(bm_specifics.meta_info(i).value())); + } else if (bm_specifics.meta_info(i).key() == "originator_cache_guid") { + originator_cache_guid = bm_specifics.meta_info(i).value(); + } else if (bm_specifics.meta_info(i).key() == + "originator_client_item_id") { + originator_client_item_id = bm_specifics.meta_info(i).value(); + } else if (bm_specifics.meta_info(i).key() == "last_send_time" && + entity.version() == 0) { + // Upgrade from legacy code, we need to prevent sending duplicate + // records which are already on sync chain + skip_record = true; + } + } + + int64_t version = entity.version(); + if (entity.version() == 0) { + record->objectId = new_object_id; + record->action = brave_sync::jslib::SyncRecord::Action::A_CREATE; + } else { + record->objectId = entity.id_string(); + if (entity.deleted()) + record->action = brave_sync::jslib::SyncRecord::Action::A_DELETE; + else + record->action = brave_sync::jslib::SyncRecord::Action::A_UPDATE; + } + + DCHECK(!record->objectId.empty()); + + MetaInfo metaInfo; + metaInfo.key = "originator_cache_guid"; + if (originator_cache_guid.empty()) { + originator_cache_guid = cache_guid; + } + metaInfo.value = originator_cache_guid; + bookmark->metaInfo.push_back(metaInfo); + + metaInfo.key = "originator_client_item_id"; + if (originator_client_item_id.empty()) { + originator_client_item_id = entity.id_string(); + } + metaInfo.value = originator_client_item_id; + bookmark->metaInfo.push_back(metaInfo); + + metaInfo.key = "version"; + metaInfo.value = std::to_string(version); + bookmark->metaInfo.push_back(metaInfo); + + metaInfo.key = "position_in_parent"; + metaInfo.value = std::to_string(entity.position_in_parent()); + bookmark->metaInfo.push_back(metaInfo); + + record->SetBookmark(std::move(bookmark)); + if (!skip_record) + record_list->push_back(std::move(record)); + } + sync_pb::CommitResponse_EntryResponse* entry_response = + response->mutable_commit()->add_entryresponse(); + CreateSuccessfulCommitResponse(entity, entry_response, new_object_id); + } + return record_list; +} + +SyncerError PostBraveCommit(sync_pb::ClientToServerMessage* message, + sync_pb::ClientToServerResponse* response, + SyncCycle* cycle) { + brave_sync::RecordsListPtr records_list = + ConvertCommitsToBraveRecords(message, response); + cycle->delegate()->OnNudgeSyncCycle(std::move(records_list)); + + return SyncerError(SyncerError::SYNCER_OK); +} + +} // namespace +} // namespace syncer diff --git a/chromium_src/components/sync/engine_impl/cycle/sync_cycle.h b/chromium_src/components/sync/engine_impl/cycle/sync_cycle.h new file mode 100644 index 000000000000..2437341a63cc --- /dev/null +++ b/chromium_src/components/sync/engine_impl/cycle/sync_cycle.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_CYCLE_SYNC_CYCLE_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_CYCLE_SYNC_CYCLE_H_ + +#include "brave/components/brave_sync/jslib_messages_fwd.h" + +#define BRAVE_SYNC_CYCLE_DELEGATE_H \ + virtual void OnNudgeSyncCycle(brave_sync::RecordsListPtr records_list) {} \ + virtual void OnPollSyncCycle(brave_sync::GetRecordsCallback cb, \ + base::WaitableEvent* wevent) {} + +#include "../../../../../../components/sync/engine_impl/cycle/sync_cycle.h" +#undef BRAVE_SYNC_CYCLE_DELEGATE_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_CYCLE_SYNC_CYCLE_H_ diff --git a/chromium_src/components/sync/engine_impl/get_updates_processor.cc b/chromium_src/components/sync/engine_impl/get_updates_processor.cc new file mode 100644 index 000000000000..77d6097e44cf --- /dev/null +++ b/chromium_src/components/sync/engine_impl/get_updates_processor.cc @@ -0,0 +1,269 @@ +/* Copyright (c) 2019 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 "components/sync/engine_impl/get_updates_processor.h" + +#include +#include +#include +#include + +namespace syncer { +namespace { +SyncerError ApplyBraveRecords(sync_pb::ClientToServerResponse*, + ModelTypeSet*, + std::unique_ptr); +} // namespace +} // namespace syncer + +#include "../../../../../components/sync/engine_impl/get_updates_processor.cc" // NOLINT +#include "base/base64.h" +#include "base/guid.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "brave/components/brave_sync/jslib_messages.h" +#include "components/sync/base/hash_util.h" +#include "components/sync/base/system_encryptor.h" +#include "components/sync/base/time.h" +#include "components/sync/engine_impl/loopback_server/loopback_server_entity.h" +#include "components/sync/nigori/cryptographer.h" +#include "components/sync/syncable/syncable_proto_util.h" +#include "url/gurl.h" + +namespace syncer { +namespace { + +using brave_sync::jslib::Bookmark; +using brave_sync::jslib::SyncRecord; +using syncable::Id; +static const char kBookmarkBarFolderServerTag[] = "bookmark_bar"; +static const char kBookmarkBarFolderName[] = "Bookmark Bar"; +static const char kOtherBookmarksFolderServerTag[] = "other_bookmarks"; +static const char kOtherBookmarksFolderName[] = "Other Bookmarks"; +static const char kSyncedBookmarksFolderServerTag[] = "synced_bookmarks"; +static const char kSyncedBookmarksFolderName[] = "Synced Bookmarks"; +// The parent tag for children of the root entity. Entities with this parent are +// referred to as top level enities. +static const char kRootParentTag[] = "0"; + +void AddBookmarkSpecifics(sync_pb::EntitySpecifics* specifics, + const SyncRecord* record) { + DCHECK(specifics); + auto bookmark = record->GetBookmark(); + sync_pb::BookmarkSpecifics* bm_specifics = specifics->mutable_bookmark(); + bm_specifics->set_url(bookmark.site.location); + + bm_specifics->set_title(bookmark.site.TryGetNonEmptyTitle()); + bm_specifics->set_creation_time_us( + TimeToProtoTime(bookmark.site.creationTime)); + bm_specifics->set_icon_url(bookmark.site.favicon); + // base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds()); + sync_pb::MetaInfo* meta_info = bm_specifics->add_meta_info(); + meta_info->set_key("order"); + meta_info->set_value(bookmark.order); + // For GetExistingObjects lookup + meta_info = bm_specifics->add_meta_info(); + meta_info->set_key("object_id"); + meta_info->set_value(record->objectId); + meta_info = bm_specifics->add_meta_info(); + meta_info->set_key("parent_object_id"); + meta_info->set_value(bookmark.parentFolderObjectId); + meta_info = bm_specifics->add_meta_info(); + meta_info->set_key("sync_timestamp"); + meta_info->set_value(std::to_string(record->syncTimestamp.ToJsTime())); +} + +void ExtractBookmarkMeta(sync_pb::SyncEntity* entity, + sync_pb::EntitySpecifics* specifics, + const Bookmark& bookmark) { + sync_pb::BookmarkSpecifics* bm_specifics = specifics->mutable_bookmark(); + for (const auto metaInfo : bookmark.metaInfo) { + // version need to be incremented + if (metaInfo.key != "version") { + sync_pb::MetaInfo* meta_info = bm_specifics->add_meta_info(); + meta_info->set_key(metaInfo.key); + meta_info->set_value(metaInfo.value); + } + if (metaInfo.key == "originator_cache_guid") { + entity->set_originator_cache_guid(metaInfo.value); + } else if (metaInfo.key == "originator_client_item_id") { + entity->set_originator_client_item_id(metaInfo.value); + } else if (metaInfo.key == "version") { + int64_t version; + bool result = base::StringToInt64(metaInfo.value, &version); + DCHECK(result); + entity->set_version(++version); + sync_pb::MetaInfo* meta_info = bm_specifics->add_meta_info(); + meta_info->set_key(metaInfo.key); + meta_info->set_value(std::to_string(version)); + } else if (metaInfo.key == "position_in_parent") { + int64_t position_in_parent; + bool result = base::StringToInt64(metaInfo.value, &position_in_parent); + DCHECK(result); + entity->set_position_in_parent(position_in_parent); + } + } +} + +void MigrateFromLegacySync(sync_pb::SyncEntity* entity) { + if (!entity->has_originator_cache_guid()) { + entity->set_originator_cache_guid("legacy_originator_cache_guid"); + } + if (!entity->has_originator_client_item_id()) { + entity->set_originator_client_item_id(base::GenerateGUID()); + } + if (!entity->has_version()) { + entity->set_version(1); + } + if (!entity->has_position_in_parent()) { + entity->set_position_in_parent(0); + } +} + +void AddRootForType(sync_pb::SyncEntity* entity, ModelType type) { + DCHECK(entity); + sync_pb::EntitySpecifics specifics; + AddDefaultFieldValue(type, &specifics); + std::string server_tag = ModelTypeToRootTag(type); + std::string name = syncer::ModelTypeToString(type); + std::string id = LoopbackServerEntity::GetTopLevelId(type); + entity->set_server_defined_unique_tag(server_tag); + entity->set_id_string(id); + entity->set_parent_id_string(kRootParentTag); + entity->set_name(name); + entity->set_version(1); + entity->set_folder(true); + entity->mutable_specifics()->CopyFrom(specifics); +} + +void AddPermanentNode(sync_pb::SyncEntity* entity, + const std::string& name, + const std::string& tag) { + DCHECK(entity); + sync_pb::EntitySpecifics specifics; + AddDefaultFieldValue(BOOKMARKS, &specifics); + std::string parent = ModelTypeToRootTag(BOOKMARKS); + std::string id = tag; + std::string parent_id = LoopbackServerEntity::CreateId(BOOKMARKS, parent); + entity->set_server_defined_unique_tag(tag); + entity->set_id_string(id); + entity->set_parent_id_string(parent_id); + entity->set_name(name); + entity->set_folder(true); + entity->set_version(1); + entity->mutable_specifics()->CopyFrom(specifics); +} + +void AddBookmarkNode(sync_pb::SyncEntity* entity, const SyncRecord* record) { + DCHECK(entity); + DCHECK(record); + DCHECK(record->has_bookmark()); + DCHECK(!record->objectId.empty()); + + auto bookmark_record = record->GetBookmark(); + + sync_pb::EntitySpecifics specifics; + AddDefaultFieldValue(BOOKMARKS, &specifics); + entity->set_id_string(record->objectId); + if (!bookmark_record.parentFolderObjectId.empty()) + entity->set_parent_id_string(bookmark_record.parentFolderObjectId); + else if (!bookmark_record.hideInToolbar) + entity->set_parent_id_string(std::string(kBookmarkBarFolderServerTag)); + else + entity->set_parent_id_string(std::string(kOtherBookmarksFolderServerTag)); + entity->set_non_unique_name(bookmark_record.site.TryGetNonEmptyTitle()); + entity->set_folder(bookmark_record.isFolder); + + ExtractBookmarkMeta(entity, &specifics, bookmark_record); + + MigrateFromLegacySync(entity); + + if (record->action == SyncRecord::Action::A_DELETE) + entity->set_deleted(true); + else + AddBookmarkSpecifics(&specifics, record); + entity->mutable_specifics()->CopyFrom(specifics); +} + +void ConstructUpdateResponse(sync_pb::GetUpdatesResponse* gu_response, + ModelTypeSet* request_types, + std::unique_ptr records) { + DCHECK(gu_response); + DCHECK(request_types); + for (ModelType type : *request_types) { + sync_pb::DataTypeProgressMarker* marker = + gu_response->add_new_progress_marker(); + marker->set_data_type_id(GetSpecificsFieldNumberFromModelType(type)); + marker->set_token("token"); + if (type == BOOKMARKS) { + google::protobuf::RepeatedPtrField entities; + AddRootForType(entities.Add(), BOOKMARKS); + AddPermanentNode(entities.Add(), kBookmarkBarFolderName, + kBookmarkBarFolderServerTag); + AddPermanentNode(entities.Add(), kOtherBookmarksFolderName, + kOtherBookmarksFolderServerTag); + // required since 84f01c4c006cf89941138f3591db129a5b3cde54 + AddPermanentNode(entities.Add(), kSyncedBookmarksFolderName, + kSyncedBookmarksFolderServerTag); + if (records) { + for (const auto& record : *records.get()) { + AddBookmarkNode(entities.Add(), record.get()); + } + } + std::copy(entities.begin(), entities.end(), + RepeatedPtrFieldBackInserter(gu_response->mutable_entries())); + } else if (type == NIGORI) { + google::protobuf::RepeatedPtrField entities; + sync_pb::EntitySpecifics specifics; + AddDefaultFieldValue(NIGORI, &specifics); + sync_pb::SyncEntity* entity = entities.Add(); + AddRootForType(entity, NIGORI); + sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); + nigori->set_encrypt_everything(false); + nigori->set_encrypt_bookmarks(false); + syncer::SystemEncryptor encryptor; + syncer::Cryptographer cryptographer(&encryptor); + KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "foobar"}; + syncer::KeyDerivationMethod method = params.derivation_params.method(); + bool add_key_result = cryptographer.AddKey(params); + DCHECK(add_key_result); + bool get_keys_result = + cryptographer.GetKeys(nigori->mutable_encryption_keybag()); + DCHECK(get_keys_result); + nigori->set_keybag_is_frozen(true); + nigori->set_keystore_migration_time(1U); + nigori->set_passphrase_type(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE); + nigori->set_custom_passphrase_key_derivation_method( + EnumKeyDerivationMethodToProto(method)); + entity->mutable_specifics()->CopyFrom(specifics); + + std::copy(entities.begin(), entities.end(), + RepeatedPtrFieldBackInserter(gu_response->mutable_entries())); + } + } + gu_response->set_changes_remaining(0); + gu_response->add_encryption_keys("dummy_encryption_key"); +} + +SyncerError ApplyBraveRecords(sync_pb::ClientToServerResponse* update_response, + ModelTypeSet* request_types, + std::unique_ptr records) { + DCHECK(update_response); + DCHECK(request_types); + sync_pb::GetUpdatesResponse* gu_response = new sync_pb::GetUpdatesResponse(); + ConstructUpdateResponse(gu_response, request_types, std::move(records)); + update_response->set_allocated_get_updates(gu_response); + return SyncerError(SyncerError::SYNCER_OK); +} + +} // namespace + +void GetUpdatesProcessor::AddBraveRecords( + std::unique_ptr records) { + brave_records_ = std::move(records); +} + +} // namespace syncer diff --git a/chromium_src/components/sync/engine_impl/get_updates_processor.h b/chromium_src/components/sync/engine_impl/get_updates_processor.h new file mode 100644 index 000000000000..e70f42654ad1 --- /dev/null +++ b/chromium_src/components/sync/engine_impl/get_updates_processor.h @@ -0,0 +1,25 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_GET_UPDATES_PROCESSOR_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_GET_UPDATES_PROCESSOR_H_ + +#include "brave/components/brave_sync/jslib_messages_fwd.h" + +namespace syncer { +using brave_sync::RecordsList; +} // namespace syncer + +#define BRAVE_GET_UPDATES_PROCESSOR_H \ + public: \ + void AddBraveRecords(std::unique_ptr records); \ + \ + private: \ + std::unique_ptr brave_records_; + +#include "../../../../../components/sync/engine_impl/get_updates_processor.h" +#undef BRAVE_GET_UPDATES_PROCESSOR_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_GET_UPDATES_PROCESSOR_H_ diff --git a/chromium_src/components/sync/engine_impl/sync_manager_impl.cc b/chromium_src/components/sync/engine_impl/sync_manager_impl.cc new file mode 100644 index 000000000000..3c3fafb9487f --- /dev/null +++ b/chromium_src/components/sync/engine_impl/sync_manager_impl.cc @@ -0,0 +1,17 @@ +/* Copyright (c) 2019 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 "components/sync/engine_impl/sync_scheduler_impl.h" + +#define BRAVE_SYNC_MANAGER_IMPL_INIT \ + static_cast(scheduler_.get()) \ + ->nudge_sync_cycle_delegate_function_ = \ + args->nudge_sync_cycle_delegate_function; \ + static_cast(scheduler_.get()) \ + ->poll_sync_cycle_delegate_function_ = \ + args->poll_sync_cycle_delegate_function; + +#include "../../../../../components/sync/engine_impl/sync_manager_impl.cc" // NOLINT +#undef BRAVE_SYNC_MANAGER_IMPL_INIT diff --git a/chromium_src/components/sync/engine_impl/sync_scheduler_impl.cc b/chromium_src/components/sync/engine_impl/sync_scheduler_impl.cc new file mode 100644 index 000000000000..beab44e2497a --- /dev/null +++ b/chromium_src/components/sync/engine_impl/sync_scheduler_impl.cc @@ -0,0 +1,32 @@ +/* Copyright (c) 2019 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 "components/sync/engine_impl/sync_scheduler_impl.h" + +#include "brave/components/brave_sync/jslib_messages.h" + +namespace syncer { + +void SyncSchedulerImpl::OnNudgeSyncCycle( + brave_sync::RecordsListPtr records_list) { + DCHECK(nudge_sync_cycle_delegate_function_); + nudge_sync_cycle_delegate_function_.Run(std::move(records_list)); +} + +void SyncSchedulerImpl::OnPollSyncCycle(brave_sync::GetRecordsCallback cb, + base::WaitableEvent* wevent) { + DCHECK(poll_sync_cycle_delegate_function_); + poll_sync_cycle_delegate_function_.Run(std::move(cb), wevent); +} + +} // namespace syncer + +#define BRAVE_SYNC_SCHEDULER_IMPL_TRY_SYNC_CYCLE_JOB \ + SyncCycle cycle(cycle_context_, this); \ + if (mode_ != CONFIGURATION_MODE) { \ + syncer_->DownloadBraveRecords(&cycle); \ + } + +#include "../../../../../components/sync/engine_impl/sync_scheduler_impl.cc" // NOLINT diff --git a/chromium_src/components/sync/engine_impl/sync_scheduler_impl.h b/chromium_src/components/sync/engine_impl/sync_scheduler_impl.h new file mode 100644 index 000000000000..8870a48224bf --- /dev/null +++ b/chromium_src/components/sync/engine_impl/sync_scheduler_impl.h @@ -0,0 +1,24 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_SYNC_SCHEDULER_IMPL_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_SYNC_SCHEDULER_IMPL_H_ + +#include "brave/components/brave_sync/jslib_messages_fwd.h" + +#define BRAVE_SYNC_SCHEDULER_IMPL_H_ \ + void OnNudgeSyncCycle(brave_sync::RecordsListPtr records_list) override; \ + void OnPollSyncCycle(brave_sync::GetRecordsCallback cb, \ + base::WaitableEvent* wevent) override; \ + \ + private: \ + friend class SyncManagerImpl; \ + brave_sync::NudgeSyncCycleDelegate nudge_sync_cycle_delegate_function_; \ + brave_sync::PollSyncCycleDelegate poll_sync_cycle_delegate_function_; + +#include "../../../../../components/sync/engine_impl/sync_scheduler_impl.h" +#undef BRAVE_SYNC_SCHEDULER_IMPL_H_ + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_SYNC_SCHEDULER_IMPL_H_ diff --git a/chromium_src/components/sync/engine_impl/syncer.cc b/chromium_src/components/sync/engine_impl/syncer.cc new file mode 100644 index 000000000000..c3376cebe95e --- /dev/null +++ b/chromium_src/components/sync/engine_impl/syncer.cc @@ -0,0 +1,40 @@ +/* Copyright (c) 2019 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/chromium_src/components/sync/engine_impl/syncer.h" + +#include +#include + +#include "base/bind.h" +#include "base/time/time.h" + +#include "../../../../../components/sync/engine_impl/syncer.cc" // NOLINT + +namespace syncer { + +using brave_sync::GetRecordsCallback; +using brave_sync::RecordsList; + +void Syncer::OnGetRecords(std::unique_ptr records) { + brave_records_ = std::move(records); +} + +void Syncer::DownloadBraveRecords(SyncCycle* cycle) { + // syncer will be alive as long as sync is enabled + brave_records_.reset(); + brave_sync::GetRecordsCallback on_get_records = + base::BindOnce(&Syncer::OnGetRecords, base::Unretained(this)); + base::WaitableEvent wevent; + cycle->delegate()->OnPollSyncCycle(std::move(on_get_records), &wevent); + // Make sure OnGetRecords will be the next task on sync thread + // it will timeout in 3 mins to prevent sync thread from being blocked as + // fail-safe + bool result = wevent.TimedWait(base::TimeDelta::FromMinutes(3)); + if (!result) + LOG(WARNING) << "WaitableEvent timed out"; +} + +} // namespace syncer diff --git a/chromium_src/components/sync/engine_impl/syncer.h b/chromium_src/components/sync/engine_impl/syncer.h new file mode 100644 index 000000000000..e0170fe93c2d --- /dev/null +++ b/chromium_src/components/sync/engine_impl/syncer.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_SYNCER_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_SYNCER_H_ + +#include "brave/components/brave_sync/jslib_messages.h" +#include "brave/components/brave_sync/jslib_messages_fwd.h" + +#define BRAVE_SYNCER_H \ + public: \ + void DownloadBraveRecords(SyncCycle* cycle); \ + \ + private: \ + void OnGetRecords(std::unique_ptr records); \ + std::unique_ptr brave_records_; + +#include "../../../../../components/sync/engine_impl/syncer.h" +#undef BRAVE_SYNCER_H + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_ENGINE_IMPL_SYNCER_H_ diff --git a/chromium_src/components/sync/syncable/write_transaction.cc b/chromium_src/components/sync/syncable/write_transaction.cc new file mode 100644 index 000000000000..77492bb22fa5 --- /dev/null +++ b/chromium_src/components/sync/syncable/write_transaction.cc @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 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/. */ + +#define BRAVE_WRITE_TRANSACTION if (close_transaction_) +#include "../../../../components/sync/syncable/write_transaction.cc" // NOLINT +#undef BRAVE_WRITE_TRANSACTION + +namespace syncer { + +WriteTransaction::WriteTransaction(const base::Location& from_here, + UserShare* share, + syncable::WriteTransaction* syncable_wr_tr) + : BaseTransaction(share), transaction_(syncable_wr_tr) { + close_transaction_ = false; +} + +} // namespace syncer diff --git a/chromium_src/components/sync/syncable/write_transaction.h b/chromium_src/components/sync/syncable/write_transaction.h new file mode 100644 index 000000000000..b96064e243a2 --- /dev/null +++ b/chromium_src/components/sync/syncable/write_transaction.h @@ -0,0 +1,19 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_SYNCABLE_WRITE_TRANSACTION_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_SYNCABLE_WRITE_TRANSACTION_H_ + +#define BRAVE_WRITE_TRANSACTION_H_ \ + WriteTransaction(const base::Location& from_here, UserShare* share, \ + syncable::WriteTransaction* syncable_wr_tr); \ + \ + private: \ + bool close_transaction_ = true; + +#include "../../../../../components/sync/syncable/write_transaction.h" +#undef BRAVE_WRITE_TRANSACTION_H_ + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_SYNCABLE_WRITE_TRANSACTION_H_ diff --git a/chromium_src/components/sync_bookmarks/bookmark_change_processor.cc b/chromium_src/components/sync_bookmarks/bookmark_change_processor.cc new file mode 100644 index 000000000000..f281a918d87e --- /dev/null +++ b/chromium_src/components/sync_bookmarks/bookmark_change_processor.cc @@ -0,0 +1,127 @@ +/* Copyright (c) 2019 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 "components/sync_bookmarks/bookmark_change_processor.h" + +#include "brave/components/brave_sync/syncer_helper.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/sync/syncable/base_transaction.h" +#include "components/sync/syncable/syncable_base_transaction.h" +#include "components/sync/syncable/syncable_write_transaction.h" +#include "components/sync/syncable/write_node.h" +#include "components/sync/syncable/write_transaction.h" + +using bookmarks::BookmarkModel; +using bookmarks::BookmarkModelObserver; +using bookmarks::BookmarkNode; +using sync_bookmarks::BookmarkChangeProcessor; + +namespace { + +class ScopedPauseObserver { + public: + explicit ScopedPauseObserver(BookmarkModel* model, + BookmarkModelObserver* observer) + : model_(model), observer_(observer) { + DCHECK_NE(observer_, nullptr); + DCHECK_NE(model_, nullptr); + model_->RemoveObserver(observer_); + } + ~ScopedPauseObserver() { model_->AddObserver(observer_); } + + private: + BookmarkModel* model_; // Not owned + BookmarkModelObserver* observer_; // Not owned +}; + +bool IsFirstLoadedFavicon(BookmarkChangeProcessor* bookmark_change_processor, + BookmarkModel* bookmark_model, + const BookmarkNode* node) { + // Avoid sending duplicate records right after applying CREATE records, + // BookmarkChangeProcessor::SetBookmarkFavicon, put favicon data into database + // BookmarkNode::favicon() and BookmarkNode::icon_url() are available only + // after first successfuly BookmarkModel::GetFavicon() which means + // BookmarkModel::OnFaviconDataAvailable has image result available. + // So we set metainfo to know if it is first time favicon load after create + // node from remote record + std::string FirstLoadedFavicon; + if (node->GetMetaInfo("FirstLoadedFavicon", &FirstLoadedFavicon)) { + if (!node->icon_url()) + return true; + ScopedPauseObserver pause(bookmark_model, bookmark_change_processor); + BookmarkNode* mutable_node = const_cast(node); + mutable_node->DeleteMetaInfo("FirstLoadedFavicon"); + return true; + } + return false; +} + +} // namespace + +namespace sync_bookmarks { + +void BookmarkChangeProcessor::MoveSyncNode( + int index, + const bookmarks::BookmarkNode* node, + const syncer::BaseTransaction* trans) { + syncer::WriteTransaction write_trans( + FROM_HERE, trans->GetUserShare(), + static_cast( + trans->GetWrappedTrans())); + syncer::WriteNode sync_node(&write_trans); + if (!model_associator_->InitSyncNodeFromChromeId(node->id(), &sync_node)) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to init sync node from chrome node", + syncer::BOOKMARKS); + error_handler()->OnUnrecoverableError(error); + return; + } + + if (!PlaceSyncNode(MOVE, node->parent(), index, &write_trans, &sync_node, + model_associator_)) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to place sync node", syncer::BOOKMARKS); + error_handler()->OnUnrecoverableError(error); + return; + } +} + +} // namespace sync_bookmarks + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_BOOKMARK_NODE_FAVICON_CHANGED \ + if (IsFirstLoadedFavicon(this, bookmark_model_, node)) \ + return; + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_UPDATE_SYNC_NODE_PROPERTIES \ + brave_sync::AddBraveMetaInfo(src, model); + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_BOOKMARK_NODE_MOVED \ + ScopedPauseObserver pause(bookmark_model_, this); \ + brave_sync::AddBraveMetaInfo(child, model); \ + SetSyncNodeMetaInfo(child, &sync_node); + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_CHILDREN_REORDERED \ + ScopedPauseObserver pause(bookmark_model_, this); \ + brave_sync::AddBraveMetaInfo(child, model); \ + SetSyncNodeMetaInfo(child, &sync_child); + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_APPLY_CHANGES_FROM_SYNC_MODEL_1 \ + bookmark_model_->SetNodeMetaInfo(dst, "FirstLoadedFavicon", "true"); + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_APPLY_CHANGES_FROM_SYNC_MODEL_2 \ + int new_index = \ + brave_sync::GetIndexByCompareOrderStartFrom(parent, it->second, 0); \ + if (it->first != new_index) { \ + model->Move(it->second, parent, new_index); \ + MoveSyncNode(new_index, it->second, trans); \ + } else // NOLINT + +#include "../../../../components/sync_bookmarks/bookmark_change_processor.cc" // NOLINT +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_BOOKMARK_NODE_FAVICON_CHANGED +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_UPDATE_SYNC_NODE_PROPERTIES +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_BOOKMARK_NODE_MOVED +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_CHILDREN_REORDERED +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_APPLY_CHANGES_FROM_SYNC_MODEL_1 +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_APPLY_CHANGES_FROM_SYNC_MODEL_2 diff --git a/chromium_src/components/sync_bookmarks/bookmark_change_processor.h b/chromium_src/components/sync_bookmarks/bookmark_change_processor.h new file mode 100644 index 000000000000..6d20851c5a68 --- /dev/null +++ b/chromium_src/components/sync_bookmarks/bookmark_change_processor.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2019 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/. */ + +#ifndef BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_CHANGE_PROCESSOR_H_ +#define BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_CHANGE_PROCESSOR_H_ + +#define BRAVE_BOOKMARK_CHANGE_PROCESSOR_H_ \ + void MoveSyncNode(int index, const bookmarks::BookmarkNode* node, \ + const syncer::BaseTransaction* trans); + +#include "../../../../../components/sync_bookmarks/bookmark_change_processor.h" +#undef BRAVE_BOOKMARK_CHANGE_PROCESSOR_H_ + +#endif // BRAVE_CHROMIUM_SRC_COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_CHANGE_PROCESSOR_H_ diff --git a/common/BUILD.gn b/common/BUILD.gn index 267d72237556..9c5481e945aa 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -25,6 +25,17 @@ source_set("pref_names") { ] } +source_set("switches") { + sources = [ + "brave_switches.cc", + "brave_switches.h", + ] + + deps = [ + "//base", + ] +} + source_set("common") { sources = [ "brave_content_client.cc", @@ -32,8 +43,6 @@ source_set("common") { "brave_isolated_worlds.h", "brave_paths.cc", "brave_paths.h", - "brave_switches.cc", - "brave_switches.h", "common_message_generator.cc", "common_message_generator.h", "importer/brave_referral.cc", @@ -80,6 +89,7 @@ source_set("common") { deps = [ ":pref_names", ":shield_exceptions", + ":switches", "//brave/chromium_src:common", "//content/public/common", ] diff --git a/common/brave_switches.cc b/common/brave_switches.cc index 28da77521409..12b2c511cb00 100644 --- a/common/brave_switches.cc +++ b/common/brave_switches.cc @@ -5,8 +5,14 @@ #include "brave/common/brave_switches.h" +#include "base/command_line.h" + namespace switches { +bool IsBraveSyncAllowedByFlag() { + return !base::CommandLine::ForCurrentProcess()->HasSwitch(kDisableBraveSync); +} + // Allows disabling the Brave extension. // This is commonly used for loading the extension manually to debug things // in debug mode with auto-reloading. diff --git a/common/brave_switches.h b/common/brave_switches.h index a62e1e74bdcd..c5557e1563a8 100644 --- a/common/brave_switches.h +++ b/common/brave_switches.h @@ -8,6 +8,10 @@ namespace switches { +// This function can be called from any thread, and the implementation doesn't +// assume it's running on the UI thread. +bool IsBraveSyncAllowedByFlag(); + // All switches in alphabetical order. The switches should be documented // alongside the definition of their values in the .cc file. extern const char kDisableBraveExtension[]; diff --git a/common/extensions/api/BUILD.gn b/common/extensions/api/BUILD.gn index 89cb2e11e48a..f758f632e644 100644 --- a/common/extensions/api/BUILD.gn +++ b/common/extensions/api/BUILD.gn @@ -1,7 +1,8 @@ +import("//brave/components/brave_sync/buildflags/buildflags.gni") import("//brave/components/brave_wallet/browser/buildflags/buildflags.gni") +import("//tools/grit/grit_rule.gni") import("//tools/json_schema_compiler/json_features.gni") import("//tools/json_schema_compiler/json_schema_api.gni") -import("//tools/grit/grit_rule.gni") json_features("api_features") { feature_type = "APIFeature" method_name = "AddBraveAPIFeatures" @@ -12,9 +13,7 @@ json_features("api_features") { ] if (brave_wallet_enabled) { - sources += [ - "_brave_wallet_api_features.json", - ] + sources += [ "_brave_wallet_api_features.json" ] } } @@ -50,13 +49,14 @@ brave_extensions_api_schema_sources = [ "brave_rewards.json", "brave_theme.json", "rewards_notifications.json", - "brave_sync.json", ] +if (enable_brave_sync) { + brave_extensions_api_schema_sources += [ "brave_sync.json" ] +} + if (brave_wallet_enabled) { - brave_extensions_api_schema_sources += [ - "brave_wallet.json" - ] + brave_extensions_api_schema_sources += [ "brave_wallet.json" ] } brave_extensions_api_uncompiled_sources = [] @@ -97,7 +97,6 @@ function_registration("generated_api_registration") { visibility = [ ":api" ] } - generated_json_strings("generated_api_json_strings") { sources = brave_extensions_api_schema_sources + brave_extensions_api_uncompiled_sources diff --git a/common/extensions/api/brave_sync.json b/common/extensions/api/brave_sync.json index 9f5210df07e2..01a1fcfa03bc 100644 --- a/common/extensions/api/brave_sync.json +++ b/common/extensions/api/brave_sync.json @@ -46,6 +46,15 @@ "favicon" : {"type" : "string", "description" : "url of favicon"} } }, + { + "id": "MetaInfo", + "type": "object", + "description": "Represents metaInfo entity", + "properties": { + "key" : {"type" : "string", "description" : "key of meta info"}, + "value" : {"type" : "string", "description" : "value of meta info"} + } + }, { "id": "Bookmark", "type": "object", @@ -55,14 +64,10 @@ "isFolder" : {"type": "boolean"}, "parentFolderObjectId" : {"type" : "binary", "optional": true}, "parentFolderObjectIdStr" : {"type" : "string", "optional": true}, - "prevObjectId" : {"type" : "binary", "optional": true}, - "prevObjectIdStr" : {"type" : "string", "optional": true}, "fields" : { "type": "array", "items": {"type": "string" }, "optional": true }, "hideInToolbar" : {"type": "boolean", "optional": true}, "order" : {"type": "string", "optional": true}, - "prevOrder" : {"type": "string", "optional": true}, - "nextOrder" : {"type": "string", "optional": true}, - "parentOrder" : {"type": "string", "optional": true} + "metaInfo" : { "type": "array", "items": {"$ref" : "MetaInfo" }, "optional": true } } }, { @@ -288,11 +293,6 @@ "type": "function", "description": "Browser informs extension page to load js sync library.", "parameters": [] - }, - { - "name": "onClearOrderMap", - "type": "function", - "description": "Browser informs extension page all portions of bookmarks are sent, so it is time to clear the order map" } ], "functions": [ @@ -418,21 +418,6 @@ } ] }, - { - "name": "saveBookmarkOrder", - "type": "function", - "description": "Browser update order of certain object", - "parameters": [ - { - "type": "string", - "name": "object_id" - }, - { - "type": "string", - "name": "order" - } - ] - }, { "name": "syncWordsPrepared", "type": "function", diff --git a/components/brave_sync/BUILD.gn b/components/brave_sync/BUILD.gn index d7c466aa5b96..eef6eee0a4e3 100644 --- a/components/brave_sync/BUILD.gn +++ b/components/brave_sync/BUILD.gn @@ -1,63 +1,99 @@ -import("buildflags/buildflags.gni") import("//brave/components/common/typescript.gni") import("//build/config/features.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") +import("buildflags/buildflags.gni") if (enable_brave_sync) { source_set("js_sync_lib_impl") { sources = [ - "brave_sync_service_impl.cc", - "brave_sync_service_impl.h", + "brave_profile_sync_service_impl.cc", + "brave_profile_sync_service_impl.h", "client/brave_sync_client.h", "client/brave_sync_client_impl.cc", "client/brave_sync_client_impl.h", - "client/bookmark_change_processor.cc", - "client/bookmark_change_processor.h", - "client/bookmark_node.cc", - "client/bookmark_node.h", - "client/client_ext_impl_data.cc", - "client/client_ext_impl_data.h", "client/client_data.cc", "client/client_data.h", + "client/client_ext_impl_data.cc", + "client/client_ext_impl_data.h", ] deps = [ + ":public", "//base", - "//components/prefs", "//components/bookmarks/browser", "//components/bookmarks/common", "//components/keyed_service/content", "//components/keyed_service/core", - "//components/prefs", "//components/pref_registry", + "//components/prefs", + "//components/prefs", "//content/public/browser", "//extensions/browser", - "//services/network/public/cpp", "//net", + "//services/network/public/cpp", "//ui/base", ] } } -source_set("core") { +source_set("jslib_messages") { sources = [ - "bookmark_order_util.cc", - "bookmark_order_util.h", - "brave_sync_prefs.cc", - "brave_sync_prefs.h", - "brave_sync_service.cc", - "brave_sync_service.h", "jslib_const.cc", "jslib_const.h", "jslib_messages.cc", "jslib_messages.h", "jslib_messages_fwd.h", - "model/change_processor.h", + ] + + deps = [ + "//base", + ] +} + +source_set("prefs") { + sources = [ + "brave_sync_prefs.cc", + "brave_sync_prefs.h", "settings.cc", "settings.h", "sync_devices.cc", "sync_devices.h", + ] + + deps = [ + "//components/prefs", + ] +} + +source_set("public") { + sources = [ + "public/brave_profile_sync_service.h", + ] + + deps = [ + "buildflags", + ] + + if (enable_brave_sync) { + deps += [ + ":core", + + # For IsBraveSyncAllowedByFlag in + # components/sync/driver/sync_driver_switches.cc + "//brave/common:switches", + ] + } +} + +source_set("core") { + sources = [ + "bookmark_order_util.cc", + "bookmark_order_util.h", + "brave_sync_service.cc", + "brave_sync_service.h", + "syncer_helper.cc", + "syncer_helper.h", "tools.cc", "tools.h", "values_conv.cc", @@ -65,23 +101,17 @@ source_set("core") { ] deps = [ + ":jslib_messages", + ":prefs", "//base", - "//components/prefs", + "//components/bookmarks/browser", "//crypto", "//extensions/buildflags", ] - - if (enable_brave_sync) { - deps += [ - ":js_sync_lib_impl", - ] - } } source_set("brave_sync") { sources = [ - "brave_sync_service_factory.h", - "brave_sync_service_factory.cc", "brave_sync_service_observer.h", ] @@ -89,19 +119,18 @@ source_set("brave_sync") { ":core", "buildflags", "//base", - "//components/bookmarks/browser", - "//components/keyed_service/content", - "//components/keyed_service/core", - "//components/pref_registry", - "//content/public/browser", ] + + if (enable_brave_sync) { + deps += [ ":js_sync_lib_impl" ] + } } pack_web_resources("generated_resources") { resource_name = "brave_sync" output_dir = "$root_gen_dir/brave/components/brave_sync" deps = [ - "ui" + "ui", ] } @@ -129,33 +158,33 @@ grit("static_resources") { repack("resources") { deps = [ - ":static_resources", ":generated_resources", + ":static_resources", ] sources = [ - "$root_gen_dir/brave/components/brave_sync/brave_sync_static.pak", "$root_gen_dir/brave/components/brave_sync/brave_sync_generated.pak", + "$root_gen_dir/brave/components/brave_sync/brave_sync_static.pak", ] output = "$root_gen_dir/brave/components/brave_sync/brave_sync_resources.pak" } -if (!is_android) { -source_set("testutil") { - testonly = true +if (enable_brave_sync) { + source_set("testutil") { + testonly = true - deps = [ - ":brave_sync", - "//base", - "//content/public/browser", - "//chrome/test:test_support", - "//testing/gtest", - ] + deps = [ + ":brave_sync", + "//base", + "//chrome/test:test_support", + "//content/public/browser", + "//testing/gtest", + ] - sources = [ - "test_util.cc", - "test_util.h", - ] -} + sources = [ + "test_util.cc", + "test_util.h", + ] + } } diff --git a/components/brave_sync/bookmark_order_util.cc b/components/brave_sync/bookmark_order_util.cc index 8c65a5984235..30fa629f9c88 100644 --- a/components/brave_sync/bookmark_order_util.cc +++ b/components/brave_sync/bookmark_order_util.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 2019 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/bookmark_order_util.h" @@ -9,6 +10,17 @@ namespace brave_sync { +namespace { + +bool CompareOrder(const std::vector& vec_left, + const std::vector& vec_right) { + // Use C++ stdlib + return std::lexicographical_compare(vec_left.begin(), vec_left.end(), + vec_right.begin(), vec_right.end()); +} + +} // namespace + std::vector OrderToIntVect(const std::string& s) { std::vector vec_s = SplitString( s, @@ -21,20 +33,144 @@ std::vector OrderToIntVect(const std::string& s) { int output = 0; bool b = base::StringToInt(vec_s[i], &output); CHECK(b); - CHECK(output >= 0); + CHECK_GE(output, 0); vec_int.emplace_back(output); } return vec_int; } +std::string ToOrderString(const std::vector& vec_int) { + std::string ret; + for (size_t i = 0; i < vec_int.size(); ++i) { + if (vec_int[i] < 0) { + return ""; + } + ret += std::to_string(vec_int[i]); + if (i != vec_int.size() - 1) { + ret += "."; + } + } + return ret; +} + bool CompareOrder(const std::string& left, const std::string& right) { // Return: true if left < right - // Split each and use C++ stdlib + // Split each and compare as int vectors std::vector vec_left = OrderToIntVect(left); std::vector vec_right = OrderToIntVect(right); - return std::lexicographical_compare(vec_left.begin(), vec_left.end(), - vec_right.begin(), vec_right.end()); + return CompareOrder(vec_left, vec_right); +} + +namespace { + +std::string GetNextOrderFromPrevOrder(std::vector* vec_prev) { + DCHECK_GT(vec_prev->size(), 2u); + int last_number = vec_prev->at(vec_prev->size() - 1); + DCHECK_GT(last_number, 0); + if (last_number <= 0) { + return ""; + } else { + vec_prev->at(vec_prev->size() - 1)++; + return ToOrderString(*vec_prev); + } +} + +std::string GetPrevOrderFromNextOrder(std::vector* vec_next) { + DCHECK_GT(vec_next->size(), 2u); + int last_number = vec_next->at(vec_next->size() - 1); + DCHECK_GT(last_number, 0); + vec_next->resize(vec_next->size() - 1); + if (last_number <= 0) { + return ""; + } else if (last_number == 1) { + return ToOrderString(*vec_next) + ".0.1"; + } else { + vec_next->push_back(last_number - 1); + return ToOrderString(*vec_next); + } +} + +} // namespace + +// Inspired by https://github.com/brave/sync/blob/staging/client/bookmarkUtil.js +std::string GetOrder(const std::string& prev, + const std::string& next, + const std::string& parent) { + if (prev.empty() && next.empty()) { + DCHECK(!parent.empty()); + return parent + ".1"; + } else if (!prev.empty() && next.empty()) { + std::vector vec_prev = OrderToIntVect(prev); + DCHECK_GT(vec_prev.size(), 2u); + // Just increase the last number, as we don't have next + return GetNextOrderFromPrevOrder(&vec_prev); + } else if (prev.empty() && !next.empty()) { + std::vector vec_next = OrderToIntVect(next); + DCHECK_GT(vec_next.size(), 2u); + // Just decrease the last number or substitute with 0.1, + // as we don't have prev + return GetPrevOrderFromNextOrder(&vec_next); + } else { + DCHECK(!prev.empty() && !next.empty()); + std::vector vec_prev = OrderToIntVect(prev); + DCHECK_GT(vec_prev.size(), 2u); + std::vector vec_next = OrderToIntVect(next); + DCHECK_GT(vec_next.size(), 2u); + DCHECK(CompareOrder(prev, next)); + + // Assume prev looks as a.b.c.d + // result candidates are: + // a.b.c.(d+1) + // a.b.c.d.1 + // a.b.c.d.0.1 + // a.b.c.d.0.0.1 + // ... + // each of them is greater than prev + + // Length of result in worse case can be one segment longer + // than length of next + // And result should be < next + + std::vector vec_result; + vec_result = vec_prev; + vec_result[vec_result.size() - 1]++; + + // Case a.b.c.(d+1) + DCHECK(CompareOrder(vec_prev, vec_result)); + if (CompareOrder(vec_result, vec_next)) { + return ToOrderString(vec_result); + } + + vec_result = vec_prev; + vec_result.push_back(1); + // Case a.b.c.d.1 + DCHECK(CompareOrder(vec_prev, vec_result)); + if (CompareOrder(vec_result, vec_next)) { + return ToOrderString(vec_result); + } + + size_t insert_at = vec_prev.size(); + size_t try_until_size = vec_next.size() + 1; + // Cases a.b.c.d.0....0.1 + while (vec_result.size() < try_until_size) { + vec_result.insert(vec_result.begin() + insert_at, 0); + DCHECK(CompareOrder(vec_prev, vec_result)); + if (CompareOrder(vec_result, vec_next)) { + return ToOrderString(vec_result); + } + } + + NOTREACHED() << "[BraveSync] " << __func__ << " prev=" << prev + << " next=" << next << " terminated with " + << ToOrderString(vec_result); + } + + NOTREACHED() << "[BraveSync] " << __func__ + << " condition is not handled prev.empty()=" << prev.empty() + << " next.empty()=" << next.empty(); + + return ""; } -} // namespace brave_sync +} // namespace brave_sync diff --git a/components/brave_sync/bookmark_order_util.h b/components/brave_sync/bookmark_order_util.h index e7f7197b4ecb..6a9d9504f695 100644 --- a/components/brave_sync/bookmark_order_util.h +++ b/components/brave_sync/bookmark_order_util.h @@ -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 2019 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/. */ #ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BOOKMARK_ORDER_UTIL_H_ #define BRAVE_COMPONENTS_BRAVE_SYNC_BOOKMARK_ORDER_UTIL_H_ @@ -11,8 +12,12 @@ namespace brave_sync { std::vector OrderToIntVect(const std::string& s); + std::string ToOrderString(const std::vector& vec_int); bool CompareOrder(const std::string& left, const std::string& right); + std::string GetOrder(const std::string& prev, + const std::string& next, + const std::string& parent); -} // namespace brave_sync + } // namespace brave_sync -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BOOKMARK_ORDER_UTIL_H_ +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BOOKMARK_ORDER_UTIL_H_ diff --git a/components/brave_sync/bookmark_order_util_unittest.cc b/components/brave_sync/bookmark_order_util_unittest.cc index 87b634593e1e..98a911177262 100644 --- a/components/brave_sync/bookmark_order_util_unittest.cc +++ b/components/brave_sync/bookmark_order_util_unittest.cc @@ -1,4 +1,5 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright (c) 2019 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/. */ @@ -8,43 +9,44 @@ namespace brave_sync { -class BookmarkOrderUtilTest : public testing::Test { -public: -protected: -private: -}; - -TEST_F(BookmarkOrderUtilTest, OrderToIntVect_EmptyString) { +TEST(BookmarkOrderUtilTest, OrderToIntVect_EmptyString) { std::vector result = OrderToIntVect(""); EXPECT_TRUE(result.empty()); } -TEST_F(BookmarkOrderUtilTest, OrderToIntVect_SingleValue) { +TEST(BookmarkOrderUtilTest, OrderToIntVect_SingleValue) { std::vector result = OrderToIntVect("1"); ASSERT_EQ(result.size(), 1u); EXPECT_EQ(result.at(0), 1); } -TEST_F(BookmarkOrderUtilTest, OrderToIntVect_TypicalValue) { +TEST(BookmarkOrderUtilTest, OrderToIntVect_TypicalValue) { std::vector result = OrderToIntVect("1.7.4"); ASSERT_EQ(result.size(), 3u); - EXPECT_TRUE(result.at(0) == 1); - EXPECT_TRUE(result.at(1) == 7); - EXPECT_TRUE(result.at(2) == 4); + EXPECT_EQ(result.at(0), 1); + EXPECT_EQ(result.at(1), 7); + EXPECT_EQ(result.at(2), 4); } -TEST_F(BookmarkOrderUtilTest, OrderToIntVect_WrongValue) { +TEST(BookmarkOrderUtilTest, OrderToIntVect_WrongValue) { std::vector result = OrderToIntVect(".."); EXPECT_TRUE(result.empty()); } -TEST_F(BookmarkOrderUtilTest, OrderToIntVect_SemiWrongValue) { +TEST(BookmarkOrderUtilTest, OrderToIntVect_SemiWrongValue) { std::vector result = OrderToIntVect(".5."); ASSERT_EQ(result.size(), 1u); EXPECT_EQ(result.at(0), 5); } -TEST_F(BookmarkOrderUtilTest, CompareOrder) { +TEST(BookmarkOrderUtilTest, ToOrderString) { + EXPECT_EQ(ToOrderString({}), ""); + EXPECT_EQ(ToOrderString({1}), "1"); + EXPECT_EQ(ToOrderString({1, 2, 3}), "1.2.3"); + EXPECT_EQ(ToOrderString({-1, 2, 3}), ""); +} + +TEST(BookmarkOrderUtilTest, CompareOrder) { EXPECT_FALSE(CompareOrder("", "")); EXPECT_TRUE(CompareOrder("1", "2")); EXPECT_TRUE(CompareOrder("1", "1.1")); @@ -58,6 +60,56 @@ TEST_F(BookmarkOrderUtilTest, CompareOrder) { EXPECT_TRUE(CompareOrder("1.7.0.1", "1.7.1")); EXPECT_TRUE(CompareOrder("1.7.0.1", "1.7.0.2")); EXPECT_FALSE(CompareOrder("1.7.0.2", "1.7.0.1")); + + EXPECT_TRUE(CompareOrder("2.0.8", "2.0.8.0.1")); + EXPECT_TRUE(CompareOrder("2.0.8.0.1", "2.0.8.1")); + + EXPECT_TRUE(CompareOrder("2.0.8", "2.0.8.0.0.1")); + EXPECT_TRUE(CompareOrder("2.0.8.0.0.1", "2.0.8.0.1")); + + EXPECT_TRUE(CompareOrder("2.0.8.10", "2.0.8.10.1")); + EXPECT_TRUE(CompareOrder("2.0.8.10.1", "2.0.8.11.1")); + + EXPECT_TRUE(CompareOrder("2.0.0.1", "2.0.1")); + + EXPECT_TRUE(CompareOrder("2.5.6.3", "2.5.7.8.2")); + EXPECT_TRUE(CompareOrder("2.5.6.3", "2.5.6.4")); + EXPECT_TRUE(CompareOrder("2.5.6.4", "2.5.7.8.2")); + + EXPECT_TRUE(CompareOrder("2.0.8.10", "2.0.8.11")); + EXPECT_TRUE(CompareOrder("2.0.8.11", "2.0.8.11.1")); +} + +TEST(BookmarkOrderUtilTest, GetOrder) { + // Ported from + // https://github.com/brave/sync/blob/staging/test/client/bookmarkUtil.js + EXPECT_EQ(GetOrder("", "2.0.1", ""), "2.0.0.1"); + + EXPECT_EQ(GetOrder("", "2.0.9", ""), "2.0.8"); + EXPECT_EQ(GetOrder("2.0.8", "", ""), "2.0.9"); + EXPECT_EQ(GetOrder("2.0.8", "2.0.9", ""), "2.0.8.1"); + + EXPECT_EQ(GetOrder("2.0.8", "2.0.8.1", ""), "2.0.8.0.1"); + EXPECT_EQ(GetOrder("2.0.8", "2.0.8.0.1", ""), "2.0.8.0.0.1"); + EXPECT_EQ(GetOrder("2.0.8", "2.0.8.0.0.1", ""), "2.0.8.0.0.0.1"); + + EXPECT_EQ(GetOrder("2.0.8.1", "2.0.9", ""), "2.0.8.2"); + EXPECT_EQ(GetOrder("2.0.8.1", "2.0.10", ""), "2.0.8.2"); + EXPECT_EQ(GetOrder("2.0.8.10", "2.0.8.15", ""), "2.0.8.11"); + + EXPECT_EQ(GetOrder("2.0.8.10", "2.0.8.15.1", ""), "2.0.8.11"); + EXPECT_EQ(GetOrder("2.0.8.10", "2.0.8.11.1", ""), "2.0.8.11"); + + EXPECT_EQ(GetOrder("2.0.8.11", "2.0.8.11.1", ""), "2.0.8.11.0.1"); + + EXPECT_EQ(GetOrder("2.0.8.10.0.1", "2.0.8.15.1", ""), "2.0.8.10.0.2"); + EXPECT_EQ(GetOrder("", "", "2.0.9"), "2.0.9.1"); + + EXPECT_EQ(GetOrder("2.5.6.3", "2.5.7.8.2", ""), "2.5.6.4"); + EXPECT_EQ(GetOrder("2.5.6.35", "2.5.7.8.2", ""), "2.5.6.36"); + + EXPECT_EQ(GetOrder("1.1.1.2", "1.1.1.2.1", ""), "1.1.1.2.0.1"); + EXPECT_EQ(GetOrder("1.1.1.2.1", "1.1.1.3", ""), "1.1.1.2.2"); } -} // namespace brave_sync +} // namespace brave_sync diff --git a/components/brave_sync/brave_profile_sync_service_impl.cc b/components/brave_sync/brave_profile_sync_service_impl.cc new file mode 100644 index 000000000000..b74054202244 --- /dev/null +++ b/components/brave_sync/brave_profile_sync_service_impl.cc @@ -0,0 +1,1023 @@ +/* Copyright 2019 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_profile_sync_service_impl.h" + +#include +#include + +#include "base/bind.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "brave/components/brave_sync/brave_sync_prefs.h" +#include "brave/components/brave_sync/brave_sync_service_observer.h" +#include "brave/components/brave_sync/client/brave_sync_client_impl.h" +#include "brave/components/brave_sync/jslib_const.h" +#include "brave/components/brave_sync/jslib_messages.h" +#include "brave/components/brave_sync/settings.h" +#include "brave/components/brave_sync/sync_devices.h" +#include "brave/components/brave_sync/syncer_helper.h" +#include "brave/components/brave_sync/tools.h" +#include "brave/components/brave_sync/values_conv.h" +#include "chrome/browser/sync/chrome_sync_client.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/signin/core/browser/account_info.h" +#include "components/sync/engine_impl/syncer.h" +#include "content/public/browser/browser_thread.h" +#include "net/base/network_interfaces.h" +#include "ui/base/models/tree_node_iterator.h" + +namespace brave_sync { + +using browser_sync::ChromeSyncClient; +using jslib::Device; +using jslib::MetaInfo; +using jslib::SyncRecord; +using jslib_const::kBookmarks; +using jslib_const::kHistorySites; +using jslib_const::kPreferences; +using jslib_const::SyncObjectData_DEVICE; +using jslib_const::SyncRecordType_PREFERENCES; +using tools::IsTimeEmpty; + +const std::vector BraveProfileSyncServiceImpl::kExponentialWaits = { + 10, 20, 40, 80}; +const int BraveProfileSyncServiceImpl::kMaxSendRetries = + BraveProfileSyncServiceImpl::kExponentialWaits.size() - 1; + +namespace { + +AccountInfo GetDummyAccountInfo() { + AccountInfo account_info; + account_info.account_id = "dummy_account_id"; + return account_info; +} + +void NotifyLogMessage(const std::string& message) { + DLOG(INFO) << message; +} + +std::string GetDeviceName() { + std::string hostname = net::GetHostName(); + if (hostname.empty()) { +#if defined(OS_MACOSX) + hostname = std::string("Mac Desktop"); +#elif defined(OS_LINUX) + hostname = std::string("Linux Desktop"); +#elif defined(OS_WIN) + hostname = std::string("Windows Desktop"); +#endif + } + return hostname; +} + +RecordsListPtr CreateDeviceCreationRecordExtension( + const std::string& deviceName, + const std::string& objectId, + const SyncRecord::Action& action, + const std::string& deviceId) { + RecordsListPtr records = std::make_unique(); + + SyncRecordPtr record = std::make_unique(); + + record->action = action; + record->deviceId = deviceId; + record->objectId = objectId; + record->objectData = SyncObjectData_DEVICE; // "device" + + std::unique_ptr device = std::make_unique(); + device->name = deviceName; + record->SetDevice(std::move(device)); + + records->emplace_back(std::move(record)); + + return records; +} + +const bookmarks::BookmarkNode* FindByObjectId(bookmarks::BookmarkModel* model, + const std::string& object_id) { + ui::TreeNodeIterator iterator( + model->root_node()); + while (iterator.has_next()) { + const bookmarks::BookmarkNode* node = iterator.Next(); + std::string node_object_id; + node->GetMetaInfo("object_id", &node_object_id); + + if (!node_object_id.empty() && object_id == node_object_id) + return node; + } + return nullptr; +} + +std::unique_ptr CreateDeleteBookmarkByObjectId( + const prefs::Prefs* brave_sync_prefs, + const std::string& object_id) { + auto record = std::make_unique(); + record->deviceId = brave_sync_prefs->GetThisDeviceId(); + record->objectData = jslib_const::SyncObjectData_BOOKMARK; + record->objectId = object_id; + record->action = jslib::SyncRecord::Action::A_DELETE; + record->syncTimestamp = base::Time::Now(); + auto bookmark = std::make_unique(); + record->SetBookmark(std::move(bookmark)); + return record; +} + +void DoDispatchGetRecordsCallback( + GetRecordsCallback cb, + std::unique_ptr records) { + std::move(cb).Run(std::move(records)); +} + +void AddSyncEntityInfo(jslib::Bookmark* bookmark, + const bookmarks::BookmarkNode* node, + const std::string& key) { + std::string value; + if (node->GetMetaInfo(key, &value)) { + MetaInfo metaInfo; + metaInfo.key = key; + metaInfo.value = value; + bookmark->metaInfo.push_back(metaInfo); + } +} + +} // namespace + +BraveProfileSyncServiceImpl::BraveProfileSyncServiceImpl(Profile* profile, + InitParams init_params) + : BraveProfileSyncService(std::move(init_params)), + brave_sync_client_(BraveSyncClient::Create(this, profile)) { + brave_sync_words_ = std::string(); + brave_sync_prefs_ = + std::make_unique(sync_client_->GetPrefService()); + + // Moniter syncs prefs required in GetSettingsAndDevices + brave_pref_change_registrar_.Init(sync_client_->GetPrefService()); + brave_pref_change_registrar_.Add( + prefs::kSyncEnabled, + base::Bind(&BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged, + base::Unretained(this))); + brave_pref_change_registrar_.Add( + prefs::kSyncDeviceName, + base::Bind(&BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged, + base::Unretained(this))); + brave_pref_change_registrar_.Add( + prefs::kSyncDeviceList, + base::Bind(&BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged, + base::Unretained(this))); + brave_pref_change_registrar_.Add( + prefs::kSyncBookmarksEnabled, + base::Bind(&BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged, + base::Unretained(this))); + brave_pref_change_registrar_.Add( + prefs::kSyncSiteSettingsEnabled, + base::Bind(&BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged, + base::Unretained(this))); + brave_pref_change_registrar_.Add( + prefs::kSyncHistoryEnabled, + base::Bind(&BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged, + base::Unretained(this))); + // TODO(darkdh): find another way to obtain bookmark model + // change introduced in 83b9663e3814ef7e53af5009d10033b89955db44 + model_ = + static_cast(sync_client_.get())->GetBookmarkModel(); + + if (!brave_sync_prefs_->GetSeed().empty() && + !brave_sync_prefs_->GetThisDeviceName().empty()) { + brave_sync_configured_ = true; + } + network_connection_tracker_->AddNetworkConnectionObserver(this); +} + +void BraveProfileSyncServiceImpl::OnNudgeSyncCycle(RecordsListPtr records) { + if (!IsBraveSyncEnabled()) + return; + + for (auto& record : *records) { + record->deviceId = brave_sync_prefs_->GetThisDeviceId(); + } + if (!records->empty()) { + if (((!brave_sync::tools::IsTimeEmpty(chain_created_time_) && + (base::Time::Now() - chain_created_time_).InSeconds() < 30u) || + brave_sync_prefs_->GetSyncDevices()->size() < 2)) { + // Store records for now + pending_send_records_.push_back(std::move(records)); + return; + } + SendAndPurgePendingRecords(); + SendSyncRecords(jslib_const::SyncRecordType_BOOKMARKS, std::move(records)); + } +} + +BraveProfileSyncServiceImpl::~BraveProfileSyncServiceImpl() { + network_connection_tracker_->RemoveNetworkConnectionObserver(this); +} + +void BraveProfileSyncServiceImpl::OnSetupSyncHaveCode( + const std::string& sync_words, + const std::string& device_name) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (sync_words.empty()) { + OnSyncSetupError("ERR_SYNC_WRONG_WORDS"); + return; + } + + if (brave_sync_initializing_) { + NotifyLogMessage("currently initializing"); + return; + } + + if (IsBraveSyncConfigured()) { + NotifyLogMessage("already configured"); + return; + } + + ForceCompleteReset(); + DCHECK(!brave_sync_prefs_->GetSyncEnabled()); + + if (device_name.empty()) + brave_sync_prefs_->SetThisDeviceName(GetDeviceName()); + else + brave_sync_prefs_->SetThisDeviceName(device_name); + brave_sync_initializing_ = true; + + brave_sync_prefs_->SetSyncEnabled(true); + brave_sync_words_ = sync_words; +} + +void BraveProfileSyncServiceImpl::OnSetupSyncNewToSync( + const std::string& device_name) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (brave_sync_initializing_) { + NotifyLogMessage("currently initializing"); + return; + } + + if (IsBraveSyncConfigured()) { + NotifyLogMessage("already configured"); + return; + } + + ForceCompleteReset(); + DCHECK(!brave_sync_prefs_->GetSyncEnabled()); + + // If the previous attempt was connect to sync chain + // and failed to receive save-init-data + brave_sync_words_.clear(); + + if (device_name.empty()) + brave_sync_prefs_->SetThisDeviceName(GetDeviceName()); + else + brave_sync_prefs_->SetThisDeviceName(device_name); + + brave_sync_initializing_ = true; + + brave_sync_prefs_->SetSyncEnabled(true); +} + +void BraveProfileSyncServiceImpl::OnDeleteDevice(const std::string& device_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + auto sync_devices = brave_sync_prefs_->GetSyncDevices(); + + const SyncDevice* device = sync_devices->GetByDeviceId(device_id); + if (device) { + const std::string device_name = device->name_; + const std::string object_id = device->object_id_; + SendDeviceSyncRecord(SyncRecord::Action::A_DELETE, device_name, device_id, + object_id); + } +} + +void BraveProfileSyncServiceImpl::OnResetSync() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + auto sync_devices = brave_sync_prefs_->GetSyncDevices(); + + if (sync_devices->size() == 0) { + // Fail safe option + VLOG(2) << "[Sync] " << __func__ << " unexpected zero device size"; + ResetSyncInternal(); + } else { + // We have to send delete record and wait for library deleted response then + // we can reset it by ResetSyncInternal() + const std::string device_id = brave_sync_prefs_->GetThisDeviceId(); + OnDeleteDevice(device_id); + reseting_ = true; + } +} + +void BraveProfileSyncServiceImpl::GetSettingsAndDevices( + const GetSettingsAndDevicesCallback& callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + auto settings = brave_sync_prefs_->GetBraveSyncSettings(); + auto devices = brave_sync_prefs_->GetSyncDevices(); + callback.Run(std::move(settings), std::move(devices)); +} + +void BraveProfileSyncServiceImpl::GetSyncWords() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // Ask sync client + std::string seed = brave_sync_prefs_->GetSeed(); + brave_sync_client_->NeedSyncWords(seed); +} + +std::string BraveProfileSyncServiceImpl::GetSeed() { + return brave_sync_prefs_->GetSeed(); +} + +void BraveProfileSyncServiceImpl::OnSetSyncEnabled( + const bool sync_this_device) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + brave_sync_prefs_->SetSyncEnabled(sync_this_device); +} + +void BraveProfileSyncServiceImpl::OnSetSyncBookmarks( + const bool sync_bookmarks) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + syncer::UserSelectableTypeSet type_set = + ProfileSyncService::GetUserSettings()->GetSelectedTypes(); + if (sync_bookmarks) + type_set.Put(syncer::UserSelectableType::kBookmarks); + else + type_set.Remove(syncer::UserSelectableType::kBookmarks); + ProfileSyncService::GetUserSettings()->SetSelectedTypes(false, type_set); + if (brave_sync_prefs_->GetSyncBookmarksEnabled() != sync_bookmarks) + brave_sync_prefs_->SetSyncBookmarksEnabled(sync_bookmarks); +} + +void BraveProfileSyncServiceImpl::OnSetSyncBrowsingHistory( + const bool sync_browsing_history) { + brave_sync_prefs_->SetSyncHistoryEnabled(sync_browsing_history); +} + +void BraveProfileSyncServiceImpl::OnSetSyncSavedSiteSettings( + const bool sync_saved_site_settings) { + brave_sync_prefs_->SetSyncSiteSettingsEnabled(sync_saved_site_settings); +} + +void BraveProfileSyncServiceImpl::BackgroundSyncStarted(bool startup) {} + +void BraveProfileSyncServiceImpl::BackgroundSyncStopped(bool shutdown) {} + +void BraveProfileSyncServiceImpl::OnSyncDebug(const std::string& message) { + NotifyLogMessage(message); +} + +void BraveProfileSyncServiceImpl::OnSyncSetupError(const std::string& error) { + if (brave_sync_initializing_) { + brave_sync_prefs_->Clear(); + brave_sync_initializing_ = false; + } + NotifySyncSetupError(error); +} + +void BraveProfileSyncServiceImpl::OnGetInitData( + const std::string& sync_version) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + Uint8Array seed; + if (!brave_sync_words_.empty()) { + VLOG(1) << "[Brave Sync] Init from sync words"; + } else if (!brave_sync_prefs_->GetSeed().empty()) { + seed = Uint8ArrayFromString(brave_sync_prefs_->GetSeed()); + VLOG(1) << "[Brave Sync] Init from prefs"; + } else { + VLOG(1) << "[Brave Sync] Init new chain"; + } + + Uint8Array device_id; + if (!brave_sync_prefs_->GetThisDeviceId().empty()) { + device_id = Uint8ArrayFromString(brave_sync_prefs_->GetThisDeviceId()); + VLOG(1) << "[Brave Sync] Init device id from prefs: " + << StrFromUint8Array(device_id); + } else { + VLOG(1) << "[Brave Sync] Init empty device id"; + } + + DCHECK(!sync_version.empty()); + // TODO(bridiver) - this seems broken because using the version we get back + // from the server (currently v1.4.2) causes things to break. What is the + // the point of having this value? + brave_sync_prefs_->SetApiVersion("0"); + + client_data::Config config; + config.api_version = brave_sync_prefs_->GetApiVersion(); + config.server_url = "https://sync.brave.com"; + config.debug = true; + brave_sync_client_->SendGotInitData(seed, device_id, config, + brave_sync_words_); +} + +void BraveProfileSyncServiceImpl::OnSaveInitData(const Uint8Array& seed, + const Uint8Array& device_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!brave_sync_initialized_); + // If we are here and brave_sync_initializing_ is false, we have came + // not from OnSetupSyncNewToSync or OnSetupSyncHaveCode. + // One case is we put wrong code words and then restarted before cleared + // kSyncEnabled pref. This should not happen. + DCHECK(brave_sync_initializing_); + + std::string seed_str = StrFromUint8Array(seed); + std::string device_id_str = StrFromUint8Array(device_id); + + std::string prev_seed_str = brave_sync_prefs_->GetPrevSeed(); + + brave_sync_words_.clear(); + DCHECK(!seed_str.empty()); + + if (prev_seed_str == seed_str) { // reconnecting to previous sync chain + brave_sync_prefs_->SetPrevSeed(std::string()); + } else if (!prev_seed_str.empty()) { // connect/create to new sync chain + // bookmark_change_processor_->Reset(true); + brave_sync_prefs_->SetPrevSeed(std::string()); + } 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); + } + + brave_sync_prefs_->SetSeed(seed_str); + brave_sync_prefs_->SetThisDeviceId(device_id_str); + + brave_sync_configured_ = true; + + brave_sync_initializing_ = false; +} + +void BraveProfileSyncServiceImpl::OnSyncReady() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + const std::string bookmarks_base_order = + brave_sync_prefs_->GetBookmarksBaseOrder(); + if (bookmarks_base_order.empty()) { + std::string platform = tools::GetPlatformName(); + brave_sync_client_->SendGetBookmarksBaseOrder( + brave_sync_prefs_->GetThisDeviceId(), platform); + // OnSyncReady will be called by OnSaveBookmarksBaseOrder + return; + } + + DCHECK(false == brave_sync_initialized_); + brave_sync_initialized_ = true; + + // For launching from legacy sync profile and also brand new profile + if (brave_sync_prefs_->GetMigratedBookmarksVersion() < 2) + SetPermanentNodesOrder(brave_sync_prefs_->GetBookmarksBaseOrder()); + + syncer::SyncPrefs sync_prefs(sync_client_->GetPrefService()); + // first time setup sync or migrated from legacy sync + if (sync_prefs.GetLastSyncedTime().is_null()) { + ProfileSyncService::GetUserSettings()->SetSelectedTypes( + false, syncer::UserSelectableTypeSet()); + // default enable bookmark + // this is important, don't change + // to brave_sync_prefs_->SetSyncBookmarksEnabled(true); + OnSetSyncBookmarks(true); + ProfileSyncService::GetUserSettings()->SetSyncRequested(true); + } +} + +syncer::ModelTypeSet BraveProfileSyncServiceImpl::GetPreferredDataTypes() + const { + // Force DEVICE_INFO type to have nudge cycle each time to fetch + // Brave sync devices. + // Will be picked up by ProfileSyncService::ConfigureDataTypeManager + return Union(ProfileSyncService::GetPreferredDataTypes(), + {syncer::DEVICE_INFO}); +} + +void BraveProfileSyncServiceImpl::OnGetExistingObjects( + const std::string& category_name, + std::unique_ptr records, + const base::Time& last_record_time_stamp, + const bool is_truncated) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + // TODO(bridiver) - what do we do with is_truncated ? + // It appears to be ignored in b-l + if (!IsTimeEmpty(last_record_time_stamp)) { + brave_sync_prefs_->SetLatestRecordTime(last_record_time_stamp); + } + + if (category_name == kBookmarks) { + auto records_and_existing_objects = + std::make_unique(); + CreateResolveList(*records.get(), records_and_existing_objects.get()); + brave_sync_client_->SendResolveSyncRecords( + category_name, std::move(records_and_existing_objects)); + } +} + +void BraveProfileSyncServiceImpl::OnResolvedSyncRecords( + const std::string& category_name, + std::unique_ptr records) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (category_name == jslib_const::kPreferences) { + OnResolvedPreferences(*records.get()); + } else if (category_name == kBookmarks) { + for (auto& record : *records) { + LoadSyncEntityInfo(record.get()); + } + // Send records to syncer + if (get_record_cb_) + sync_thread_->task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&DoDispatchGetRecordsCallback, + std::move(get_record_cb_), std::move(records))); + SignalWaitableEvent(); + } else if (category_name == kHistorySites) { + NOTIMPLEMENTED(); + } +} + +void BraveProfileSyncServiceImpl::OnDeletedSyncUser() { + NOTIMPLEMENTED(); +} + +void BraveProfileSyncServiceImpl::OnDeleteSyncSiteSettings() { + NOTIMPLEMENTED(); +} + +void BraveProfileSyncServiceImpl::OnSaveBookmarksBaseOrder( + const std::string& order) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!order.empty()); + brave_sync_prefs_->SetBookmarksBaseOrder(order); + OnSyncReady(); +} + +void BraveProfileSyncServiceImpl::OnSyncWordsPrepared( + const std::string& words) { + NotifyHaveSyncWords(words); +} + +int BraveProfileSyncServiceImpl::GetDisableReasons() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + // legacy sync only support bookmark sync so we have to wait for migration + // complete before enable sync engine + if (IsBraveSyncEnabled() && + brave_sync_prefs_->GetMigratedBookmarksVersion() >= 2) + return syncer::SyncService::DISABLE_REASON_NONE; + // kSyncManaged is set by Brave so it will contain + // DISABLE_REASON_ENTERPRISE_POLICY and + // SaveCardBubbleControllerImpl::ShouldShowSignInPromo will return false. + return ProfileSyncService::GetDisableReasons(); +} + +CoreAccountInfo BraveProfileSyncServiceImpl::GetAuthenticatedAccountInfo() + const { + return GetDummyAccountInfo(); +} + +bool BraveProfileSyncServiceImpl::IsAuthenticatedAccountPrimary() const { + return true; +} + +void BraveProfileSyncServiceImpl::OnConnectionChanged( + network::mojom::ConnectionType type) { + if (type == network::mojom::ConnectionType::CONNECTION_NONE) + SignalWaitableEvent(); +} + +void BraveProfileSyncServiceImpl::Shutdown() { + SignalWaitableEvent(); + syncer::ProfileSyncService::Shutdown(); +} + +void BraveProfileSyncServiceImpl::NotifySyncSetupError( + const std::string& error) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + for (auto& observer : BraveSyncService::observers_) + observer.OnSyncSetupError(this, error); +} + +void BraveProfileSyncServiceImpl::NotifySyncStateChanged() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + for (auto& observer : BraveSyncService::observers_) + observer.OnSyncStateChanged(this); +} + +void BraveProfileSyncServiceImpl::NotifyHaveSyncWords( + const std::string& sync_words) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + for (auto& observer : BraveSyncService::observers_) + observer.OnHaveSyncWords(this, sync_words); +} + +void BraveProfileSyncServiceImpl::ResetSyncInternal() { + SignalWaitableEvent(); + brave_sync_prefs_->SetPrevSeed(brave_sync_prefs_->GetSeed()); + + brave_sync_prefs_->Clear(); + + brave_sync_configured_ = false; + brave_sync_initialized_ = false; + + brave_sync_prefs_->SetSyncEnabled(false); + ProfileSyncService::GetUserSettings()->SetSyncRequested(false); + + // brave sync doesn't support pause sync so treating every new sync chain as + // first time setup + syncer::SyncPrefs sync_prefs(sync_client_->GetPrefService()); + sync_prefs.SetLastSyncedTime(base::Time()); + + reseting_ = false; +} + +void BraveProfileSyncServiceImpl::ForceCompleteReset() { + if (reseting_) { + ResetSyncInternal(); + } +} + +void BraveProfileSyncServiceImpl::SetPermanentNodesOrder( + const std::string& base_order) { + DCHECK(model_); + DCHECK(!base_order.empty()); + std::string order; + model_->bookmark_bar_node()->GetMetaInfo("order", &order); + if (order.empty()) { + model_->SetNodeMetaInfo(model_->bookmark_bar_node(), "order", + base_order + "1"); + } + order.clear(); + model_->other_node()->GetMetaInfo("order", &order); + if (order.empty()) { + model_->SetNodeMetaInfo(model_->other_node(), "order", base_order + "2"); + } + brave_sync_prefs_->SetMigratedBookmarksVersion(2); +} + +std::unique_ptr +BraveProfileSyncServiceImpl::BookmarkNodeToSyncBookmark( + const bookmarks::BookmarkNode* node) { + if (node->is_permanent_node() || !node->parent()) + return std::unique_ptr(); + + auto record = std::make_unique(); + record->deviceId = brave_sync_prefs_->GetThisDeviceId(); + record->objectData = jslib_const::SyncObjectData_BOOKMARK; + + auto bookmark = std::make_unique(); + bookmark->site.location = node->url().spec(); + bookmark->site.title = base::UTF16ToUTF8(node->GetTitledUrlNodeTitle()); + bookmark->site.customTitle = base::UTF16ToUTF8(node->GetTitle()); + // bookmark->site.lastAccessedTime - ignored + bookmark->site.creationTime = node->date_added(); + bookmark->site.favicon = node->icon_url() ? node->icon_url()->spec() : ""; + // Url may have type OTHER_NODE if it is in Deleted Bookmarks + bookmark->isFolder = (node->type() != bookmarks::BookmarkNode::URL && + node->type() != bookmarks::BookmarkNode::OTHER_NODE); + bookmark->hideInToolbar = node->parent() != model_->bookmark_bar_node(); + + std::string object_id; + node->GetMetaInfo("object_id", &object_id); + record->objectId = object_id; + + std::string parent_object_id; + node->parent()->GetMetaInfo("object_id", &parent_object_id); + bookmark->parentFolderObjectId = parent_object_id; + + std::string order; + node->GetMetaInfo("order", &order); + DCHECK(!order.empty()); + bookmark->order = order; + + std::string sync_timestamp; + node->GetMetaInfo("sync_timestamp", &sync_timestamp); + DCHECK(!sync_timestamp.empty()); + + record->syncTimestamp = base::Time::FromJsTime(std::stod(sync_timestamp)); + + record->action = jslib::SyncRecord::Action::A_UPDATE; + + AddSyncEntityInfo(bookmark.get(), node, "originator_cache_guid"); + AddSyncEntityInfo(bookmark.get(), node, "originator_client_item_id"); + AddSyncEntityInfo(bookmark.get(), node, "version"); + AddSyncEntityInfo(bookmark.get(), node, "position_in_parent"); + + record->SetBookmark(std::move(bookmark)); + + return record; +} + +void BraveProfileSyncServiceImpl::SaveSyncEntityInfo( + const jslib::SyncRecord* record) { + auto* node = FindByObjectId(model_, record->objectId); + // no need to save for DELETE + if (node) { + auto& bookmark = record->GetBookmark(); + for (auto& meta_info : bookmark.metaInfo) { + model_->SetNodeMetaInfo(node, meta_info.key, meta_info.value); + } + } +} + +void BraveProfileSyncServiceImpl::LoadSyncEntityInfo( + jslib::SyncRecord* record) { + auto* node = FindByObjectId(model_, record->objectId); + if (node) { + auto* bookmark = record->mutable_bookmark(); + if (!bookmark->metaInfo.empty()) + return; + AddSyncEntityInfo(bookmark, node, "originator_cache_guid"); + AddSyncEntityInfo(bookmark, node, "originator_client_item_id"); + AddSyncEntityInfo(bookmark, node, "position_in_parent"); + std::string s_version; + // Version needs to be incremented by 1 for legacy sync to emulate + // GetUpdateProcessor behavior + if (node->GetMetaInfo("version", &s_version)) { + int64_t version; + bool result = base::StringToInt64(s_version, &version); + DCHECK(result); + MetaInfo metaInfo; + metaInfo.key = "version"; + metaInfo.value = std::to_string(++version); + bookmark->metaInfo.push_back(metaInfo); + } + } +} + +void BraveProfileSyncServiceImpl::CreateResolveList( + const std::vector>& records, + SyncRecordAndExistingList* records_and_existing_objects) { + const auto& this_device_id = brave_sync_prefs_->GetThisDeviceId(); + for (const auto& record : records) { + // Ignore records from ourselves to avoid mess on merge + if (record->deviceId == this_device_id) { + // Remove Acked sent records + brave_sync_prefs_->RemoveFromRecordsToResend(record->objectId); + continue; + } + auto resolved_record = std::make_unique(); + resolved_record->first = SyncRecord::Clone(*record); + auto* node = FindByObjectId(model_, record->objectId); + if (node) { + resolved_record->second = BookmarkNodeToSyncBookmark(node); + } + + records_and_existing_objects->push_back(std::move(resolved_record)); + } +} + +void BraveProfileSyncServiceImpl::FetchSyncRecords(const bool bookmarks, + const bool history, + const bool preferences, + int max_records) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(bookmarks || history || preferences); + if (!(bookmarks || history || preferences)) { + return; + } + + std::vector category_names; + if (history) { + category_names.push_back(kHistorySites); // "HISTORY_SITES"; + } + if (bookmarks) { + category_names.push_back(kBookmarks); // "BOOKMARKS"; + } + if (preferences) { + category_names.push_back(kPreferences); // "PREFERENCES"; + } + + brave_sync_prefs_->SetLastFetchTime(base::Time::Now()); + + base::Time start_at_time = brave_sync_prefs_->GetLatestRecordTime(); + brave_sync_client_->SendFetchSyncRecords(category_names, start_at_time, + max_records); +} + +void BraveProfileSyncServiceImpl::SendCreateDevice() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + std::string device_name = brave_sync_prefs_->GetThisDeviceName(); + std::string object_id = tools::GenerateObjectId(); + std::string device_id = brave_sync_prefs_->GetThisDeviceId(); + CHECK(!device_id.empty()); + + SendDeviceSyncRecord(SyncRecord::Action::A_CREATE, device_name, device_id, + object_id); +} + +void BraveProfileSyncServiceImpl::SendDeviceSyncRecord( + const int action, + const std::string& device_name, + const std::string& device_id, + const std::string& object_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + RecordsListPtr records = CreateDeviceCreationRecordExtension( + device_name, object_id, static_cast(action), + device_id); + SendSyncRecords(SyncRecordType_PREFERENCES, std::move(records)); +} + +void BraveProfileSyncServiceImpl::OnResolvedPreferences( + const RecordsList& records) { + const std::string this_device_id = brave_sync_prefs_->GetThisDeviceId(); + bool this_device_deleted = false; + bool contains_only_one_device = false; + + auto sync_devices = brave_sync_prefs_->GetSyncDevices(); + auto old_devices_size = sync_devices->size(); + for (const auto& record : records) { + DCHECK(record->has_device() || record->has_sitesetting()); + if (record->has_device()) { + bool actually_merged = false; + sync_devices->Merge( + SyncDevice(record->GetDevice().name, record->objectId, + record->deviceId, record->syncTimestamp.ToJsTime()), + record->action, &actually_merged); + this_device_deleted = + this_device_deleted || + (record->deviceId == this_device_id && + record->action == SyncRecord::Action::A_DELETE && actually_merged); + contains_only_one_device = + sync_devices->size() < 2 && + record->action == SyncRecord::Action::A_DELETE && actually_merged; + } + } // for each device + + brave_sync_prefs_->SetSyncDevices(*sync_devices); + + if (old_devices_size < 2 && sync_devices->size() >= 2) { + // Save chain creation time to send bookmarks 30 sec after + chain_created_time_ = base::Time::Now(); + } + if (!tools::IsTimeEmpty(chain_created_time_) && + (base::Time::Now() - chain_created_time_).InSeconds() > 30u) { + SendAndPurgePendingRecords(); + } + + if (this_device_deleted) { + ResetSyncInternal(); + } 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 BraveProfileSyncServiceImpl::OnBraveSyncPrefsChanged( + const std::string& pref) { + if (pref == prefs::kSyncEnabled) { + brave_sync_client_->OnSyncEnabledChanged(); + } + NotifySyncStateChanged(); +} + +#if BUILDFLAG(ENABLE_EXTENSIONS) +BraveSyncClient* BraveProfileSyncServiceImpl::GetBraveSyncClient() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return brave_sync_client_.get(); +} +#endif + +bool BraveProfileSyncServiceImpl::IsBraveSyncEnabled() const { + return brave_sync_prefs_->GetSyncEnabled(); +} + +bool BraveProfileSyncServiceImpl::IsBraveSyncInitialized() const { + return brave_sync_initialized_; +} + +bool BraveProfileSyncServiceImpl::IsBraveSyncConfigured() const { + return brave_sync_configured_ && + // When there is 0 or 1 device, it means chain is not completely + // created, so we should give a chance to make force reset in + // |OnSetupSyncHaveCode| or in |OnSetupSyncNewToSync| + (brave_sync_prefs_->GetSyncDevices()->size() >= 2); +} + +void BraveProfileSyncServiceImpl::OnPollSyncCycle(GetRecordsCallback cb, + base::WaitableEvent* wevent) { + if (!IsBraveSyncEnabled()) + return; + + if (IsTimeEmpty(brave_sync_prefs_->GetLastFetchTime())) + SendCreateDevice(); + brave_sync_client_->SendFetchSyncDevices(); + + if (!brave_sync_initialized_) { + wevent->Signal(); + return; + } + + get_record_cb_ = std::move(cb); + wevent_ = wevent; + + const bool bookmarks = brave_sync_prefs_->GetSyncBookmarksEnabled(); + const bool history = brave_sync_prefs_->GetSyncHistoryEnabled(); + const bool preferences = brave_sync_prefs_->GetSyncSiteSettingsEnabled(); + FetchSyncRecords(bookmarks, history, preferences, 1000); + ResendSyncRecords(jslib_const::SyncRecordType_BOOKMARKS); +} + +void BraveProfileSyncServiceImpl::SignalWaitableEvent() { + std::move(get_record_cb_); + if (wevent_) { + wevent_->Signal(); + wevent_ = nullptr; + } +} + +BraveSyncService* BraveProfileSyncServiceImpl::GetSyncService() const { + return static_cast( + const_cast(this)); +} + +void BraveProfileSyncServiceImpl::SendAndPurgePendingRecords() { + for (auto& records_to_send : pending_send_records_) { + SendSyncRecords(jslib_const::SyncRecordType_BOOKMARKS, + std::move(records_to_send)); + } + pending_send_records_.clear(); +} + +void BraveProfileSyncServiceImpl::SendSyncRecords( + const std::string& category_name, + RecordsListPtr records) { + brave_sync_client_->SendSyncRecords(category_name, *records); + if (category_name == kBookmarks) { + for (auto& record : *records) { + SaveSyncEntityInfo(record.get()); + std::unique_ptr meta = + std::make_unique(); + meta->SetInteger("send_retry_number", 0); + meta->SetDouble("sync_timestamp", record->syncTimestamp.ToJsTime()); + brave_sync_prefs_->AddToRecordsToResend(record->objectId, + std::move(meta)); + } + } +} + +void BraveProfileSyncServiceImpl::ResendSyncRecords( + const std::string& category_name) { + if (category_name == kBookmarks) { + RecordsListPtr records = std::make_unique(); + std::vector records_to_resend = + brave_sync_prefs_->GetRecordsToResend(); + if (records_to_resend.empty()) + return; + for (auto& object_id : records_to_resend) { + auto* node = FindByObjectId(model_, object_id); + + // Check resend interval + const base::DictionaryValue* meta = + brave_sync_prefs_->GetRecordToResendMeta(object_id); + DCHECK(meta); + int current_retry_number = kMaxSendRetries; + meta->GetInteger("send_retry_number", ¤t_retry_number); + DCHECK_GE(current_retry_number, 0); + double sync_timestamp = 0; + meta->GetDouble("sync_timestamp", &sync_timestamp); + DCHECK(!base::Time::FromJsTime(sync_timestamp).is_null()); + + if ((base::Time::Now() - base::Time::FromJsTime(sync_timestamp)) < + GetRetryExponentialWaitAmount(current_retry_number)) + continue; + + // Increase retry number + if (++current_retry_number > kMaxSendRetries) + current_retry_number = kMaxSendRetries; + std::unique_ptr new_meta = + base::DictionaryValue::From( + std::make_unique(meta->Clone())); + new_meta->SetInteger("send_retry_number", current_retry_number); + brave_sync_prefs_->SetRecordToResendMeta(object_id, std::move(new_meta)); + + if (node) { + records->push_back(BookmarkNodeToSyncBookmark(node)); + } else { + records->push_back( + CreateDeleteBookmarkByObjectId(brave_sync_prefs_.get(), object_id)); + } + } + if (!records->empty()) + brave_sync_client_->SendSyncRecords(category_name, *records); + } +} + +// static +base::TimeDelta BraveProfileSyncServiceImpl::GetRetryExponentialWaitAmount( + int retry_number) { + DCHECK_LE(retry_number, kMaxSendRetries); + + if (retry_number > kMaxSendRetries) { + retry_number = kMaxSendRetries; + } + return base::TimeDelta::FromMinutes(kExponentialWaits[retry_number]); +} + +// static +std::vector +BraveProfileSyncServiceImpl::GetExponentialWaitsForTests() { + return kExponentialWaits; +} + +} // namespace brave_sync diff --git a/components/brave_sync/brave_profile_sync_service_impl.h b/components/brave_sync/brave_profile_sync_service_impl.h new file mode 100644 index 000000000000..35d65b6c6da8 --- /dev/null +++ b/components/brave_sync/brave_profile_sync_service_impl.h @@ -0,0 +1,228 @@ +/* Copyright 2019 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/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_PROFILE_SYNC_SERVICE_IMPL_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_PROFILE_SYNC_SERVICE_IMPL_H_ + +#include +#include +#include + +#include "brave/components/brave_sync/brave_sync_service.h" +#include "brave/components/brave_sync/client/brave_sync_client.h" +#include "brave/components/brave_sync/jslib_messages_fwd.h" +#include "brave/components/brave_sync/public/brave_profile_sync_service.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/sync/driver/profile_sync_service.h" +#include "services/network/public/cpp/network_connection_tracker.h" + +FORWARD_DECLARE_TEST(BraveSyncServiceTest, BookmarkAdded); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, BookmarkDeleted); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, GetSyncWords); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, GetSeed); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnBraveSyncPrefsChanged); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnDeleteDevice); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnResetSync); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, ClientOnGetInitData); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnGetInitData); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSaveBookmarksBaseOrder); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncPrefsChanged); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncDebug); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, StartSyncNonDeviceRecords); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncReadyNewToSync); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnGetExistingObjects); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, + OnSetupSyncHaveCode_Reset_SetupAgain); +FORWARD_DECLARE_TEST(BraveSyncServiceTest, ExponentialResend); + +class BraveSyncServiceTest; + +namespace brave_sync { +namespace prefs { +class Prefs; +} // namespace prefs + +class BraveProfileSyncServiceImpl + : public BraveProfileSyncService, + public BraveSyncService, + public network::NetworkConnectionTracker::NetworkConnectionObserver, + public SyncMessageHandler { + public: + explicit BraveProfileSyncServiceImpl(Profile* profile, + InitParams init_params); + + ~BraveProfileSyncServiceImpl() override; + + // BraveSyncService implementation + void OnSetupSyncHaveCode(const std::string& sync_words, + const std::string& device_name) override; + void OnSetupSyncNewToSync(const std::string& device_name) override; + void OnDeleteDevice(const std::string& device_id) override; + void OnResetSync() override; + void GetSettingsAndDevices( + const GetSettingsAndDevicesCallback& callback) override; + void GetSyncWords() override; + std::string GetSeed() override; + void OnSetSyncEnabled(const bool sync_this_device) override; + void OnSetSyncBookmarks(const bool sync_bookmarks) override; + void OnSetSyncBrowsingHistory(const bool sync_browsing_history) override; + void OnSetSyncSavedSiteSettings(const bool sync_saved_site_settings) override; + + // SyncMessageHandler implementation + void BackgroundSyncStarted(bool startup) override; + void BackgroundSyncStopped(bool shutdown) override; + void OnSyncDebug(const std::string& message) override; + void OnSyncSetupError(const std::string& error) override; + void OnGetInitData(const std::string& sync_version) override; + void OnSaveInitData(const brave_sync::Uint8Array& seed, + const brave_sync::Uint8Array& device_id) override; + void OnSyncReady() override; + void OnGetExistingObjects(const std::string& category_name, + std::unique_ptr records, + const base::Time& last_record_time_stamp, + const bool is_truncated) override; + void OnResolvedSyncRecords( + const std::string& category_name, + std::unique_ptr records) override; + void OnDeletedSyncUser() override; + void OnDeleteSyncSiteSettings() override; + void OnSaveBookmarksBaseOrder(const std::string& order) override; + void OnSyncWordsPrepared(const std::string& words) override; + + // syncer::SyncService implementation + int GetDisableReasons() const override; + CoreAccountInfo GetAuthenticatedAccountInfo() const override; + bool IsAuthenticatedAccountPrimary() const override; + + // NetworkConnectionTracker::NetworkConnectionObserver implementation. + void OnConnectionChanged(network::mojom::ConnectionType type) override; + + // KeyedService implementation. This must be called exactly + // once (before this object is destroyed). + void Shutdown() override; + +#if BUILDFLAG(ENABLE_EXTENSIONS) + BraveSyncClient* GetBraveSyncClient() override; +#endif + + bool IsBraveSyncEnabled() const override; + bool IsBraveSyncInitialized() const; + bool IsBraveSyncConfigured() const; + + syncer::ModelTypeSet GetPreferredDataTypes() const override; + + void OnNudgeSyncCycle(brave_sync::RecordsListPtr records_list) override; + void OnPollSyncCycle(brave_sync::GetRecordsCallback cb, + base::WaitableEvent* wevent) override; + + BraveSyncService* GetSyncService() const override; + + private: + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, BookmarkAdded); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, BookmarkDeleted); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, GetSyncWords); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, GetSeed); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnBraveSyncPrefsChanged); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnDeleteDevice); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, + OnDeleteDeviceWhenSelfDeleted); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnResetSync); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, ClientOnGetInitData); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSaveBookmarksBaseOrder); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnGetInitData); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncPrefsChanged); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncDebug); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, StartSyncNonDeviceRecords); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncReadyNewToSync); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnGetExistingObjects); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, + OnSetupSyncHaveCode_Reset_SetupAgain); + FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, ExponentialResend); + friend class ::BraveSyncServiceTest; + + void SignalWaitableEvent(); + void FetchSyncRecords(const bool bookmarks, + const bool history, + const bool preferences, + int max_records); + void SendCreateDevice(); + void SendDeviceSyncRecord(const int action, + const std::string& device_name, + const std::string& device_id, + const std::string& object_id); + void OnResolvedPreferences(const brave_sync::RecordsList& records); + void OnBraveSyncPrefsChanged(const std::string& pref); + void NotifySyncSetupError(const std::string& error); + void NotifySyncStateChanged(); + void NotifyHaveSyncWords(const std::string& sync_words); + + void ResetSyncInternal(); + void ForceCompleteReset(); + bool GetResettingForTest() const { return reseting_; } + + void SetPermanentNodesOrder(const std::string& base_order); + + std::unique_ptr BookmarkNodeToSyncBookmark( + const bookmarks::BookmarkNode* node); + // These SyncEntityInfo is for legacy device who doesn't send meta info for + // sync entity + void SaveSyncEntityInfo(const jslib::SyncRecord* record); + void LoadSyncEntityInfo(jslib::SyncRecord* record); + + void CreateResolveList( + const std::vector>& records, + SyncRecordAndExistingList* records_and_existing_objects); + + void SendAndPurgePendingRecords(); + + void SendSyncRecords(const std::string& category_name, + RecordsListPtr records); + void ResendSyncRecords(const std::string& category_name); + + static base::TimeDelta GetRetryExponentialWaitAmount(int retry_number); + static std::vector GetExponentialWaitsForTests(); + static const std::vector kExponentialWaits; + static const int kMaxSendRetries; + + std::unique_ptr brave_sync_prefs_; + // True when is in active sync chain + bool brave_sync_configured_ = false; + + // True if we have received SyncReady from JS lib + bool brave_sync_initialized_ = false; + + // Prevent two sequential calls OnSetupSyncHaveCode or OnSetupSyncNewToSync + // while being initializing + bool brave_sync_initializing_ = false; + + bool reseting_ = false; + + std::string brave_sync_words_; + + brave_sync::GetRecordsCallback get_record_cb_; + base::WaitableEvent* wevent_ = nullptr; + + // Registrar used to monitor the brave_profile prefs. + PrefChangeRegistrar brave_pref_change_registrar_; + + bookmarks::BookmarkModel* model_ = nullptr; + + std::unique_ptr brave_sync_client_; + + base::Time chain_created_time_; + std::vector pending_send_records_; + + // Used to ensure that certain operations are performed on the sequence that + // this object was created on. + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(BraveProfileSyncServiceImpl); +}; +} // namespace brave_sync + +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_PROFILE_SYNC_SERVICE_IMPL_H_ diff --git a/components/brave_sync/brave_sync_prefs.cc b/components/brave_sync/brave_sync_prefs.cc index 65ed1fc7c72e..ff5402bb90b3 100644 --- a/components/brave_sync/brave_sync_prefs.cc +++ b/components/brave_sync/brave_sync_prefs.cc @@ -5,10 +5,13 @@ #include "brave/components/brave_sync/brave_sync_prefs.h" -#include "brave/components/brave_sync/brave_sync_service.h" +#include + #include "brave/components/brave_sync/settings.h" #include "brave/components/brave_sync/sync_devices.h" +#include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" namespace brave_sync { namespace prefs { @@ -28,9 +31,34 @@ const char kSyncDeviceList[] = "brave_sync.device_list"; const char kSyncApiVersion[] = "brave_sync.api_version"; const char kSyncMigrateBookmarksVersion[] = "brave_sync.migrate_bookmarks_version"; +const char kSyncRecordsToResend[] = "brave_sync_records_to_resend"; +const char kSyncRecordsToResendMeta[] = "brave_sync_records_to_resend_meta"; Prefs::Prefs(PrefService* pref_service) : pref_service_(pref_service) {} +void Prefs::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()); + + registry->RegisterBooleanPref(prefs::kSyncEnabled, false); + registry->RegisterBooleanPref(prefs::kSyncBookmarksEnabled, false); + registry->RegisterBooleanPref(prefs::kSyncSiteSettingsEnabled, false); + registry->RegisterBooleanPref(prefs::kSyncHistoryEnabled, false); + + registry->RegisterTimePref(prefs::kSyncLatestRecordTime, base::Time()); + registry->RegisterTimePref(prefs::kSyncLastFetchTime, base::Time()); + + registry->RegisterStringPref(prefs::kSyncDeviceList, std::string()); + registry->RegisterStringPref(prefs::kSyncApiVersion, std::string("0")); + registry->RegisterIntegerPref(prefs::kSyncMigrateBookmarksVersion, 0); + + registry->RegisterListPref(prefs::kSyncRecordsToResend); + registry->RegisterDictionaryPref(prefs::kSyncRecordsToResendMeta); +} + std::string Prefs::GetSeed() const { return pref_service_->GetString(kSyncSeed); } @@ -73,8 +101,7 @@ void Prefs::SetBookmarksBaseOrder(const std::string& order) { } bool Prefs::GetSyncEnabled() const { - return BraveSyncService::is_enabled() && - pref_service_->GetBoolean(kSyncEnabled); + return pref_service_->GetBoolean(kSyncEnabled); } void Prefs::SetSyncEnabled(const bool sync_this_device) { @@ -162,10 +189,52 @@ void Prefs::SetApiVersion(const std::string& api_version) { int Prefs::GetMigratedBookmarksVersion() { return pref_service_->GetInteger(kSyncMigrateBookmarksVersion); } + void Prefs::SetMigratedBookmarksVersion(const int migrate_bookmarks) { pref_service_->SetInteger(kSyncMigrateBookmarksVersion, migrate_bookmarks); } +std::vector Prefs::GetRecordsToResend() const { + std::vector result; + const base::Value* records = pref_service_->GetList(kSyncRecordsToResend); + for (const base::Value& record : records->GetList()) { + result.push_back(record.GetString()); + } + return result; +} + +void Prefs::AddToRecordsToResend(const std::string& object_id, + std::unique_ptr meta) { + ListPrefUpdate list_update(pref_service_, kSyncRecordsToResend); + list_update->GetList().emplace_back(object_id); + SetRecordToResendMeta(object_id, std::move(meta)); +} + +void Prefs::RemoveFromRecordsToResend(const std::string& object_id) { + ListPrefUpdate list_update(pref_service_, kSyncRecordsToResend); + base::Erase(list_update->GetList(), base::Value(object_id)); + DictionaryPrefUpdate dict_update(pref_service_, kSyncRecordsToResendMeta); + dict_update->RemoveKey(object_id); +} + +const base::DictionaryValue* Prefs::GetRecordToResendMeta( + const std::string& object_id) const { + const base::DictionaryValue* dict = + pref_service_->GetDictionary(kSyncRecordsToResendMeta); + const base::DictionaryValue* meta = nullptr; + const base::Value* meta_value = dict->FindDictKey(object_id); + if (meta_value) { + meta_value->GetAsDictionary(&meta); + } + return meta; +} + +void Prefs::SetRecordToResendMeta(const std::string& object_id, + std::unique_ptr meta) { + DictionaryPrefUpdate dict_update(pref_service_, kSyncRecordsToResendMeta); + dict_update->SetDictionary(object_id, std::move(meta)); +} + void Prefs::Clear() { pref_service_->ClearPref(kSyncDeviceId); pref_service_->ClearPref(kSyncSeed); @@ -180,6 +249,8 @@ void Prefs::Clear() { pref_service_->ClearPref(kSyncDeviceList); pref_service_->ClearPref(kSyncApiVersion); pref_service_->ClearPref(kSyncMigrateBookmarksVersion); + pref_service_->ClearPref(kSyncRecordsToResend); + pref_service_->ClearPref(kSyncRecordsToResendMeta); } } // namespace prefs diff --git a/components/brave_sync/brave_sync_prefs.h b/components/brave_sync/brave_sync_prefs.h index 1941307950f7..3efd75cef486 100644 --- a/components/brave_sync/brave_sync_prefs.h +++ b/components/brave_sync/brave_sync_prefs.h @@ -6,10 +6,12 @@ #ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_PREFS_H_ #define BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_PREFS_H_ -#include #include +#include +#include #include "base/macros.h" +#include "base/values.h" class PrefService; class Profile; @@ -18,6 +20,10 @@ namespace base { class Time; } +namespace user_prefs { +class PrefRegistrySyncable; +} + namespace brave_sync { class Settings; @@ -57,11 +63,17 @@ extern const char kSyncApiVersion[]; // The version of bookmarks state: 0,1,... . // Current to migrate to is 1. extern const char kSyncMigrateBookmarksVersion[]; +// Cached object_id list for unconfirmed records +extern const char kSyncRecordsToResend[]; +// Meta info of kSyncRecordsToResend +extern const char kSyncRecordsToResendMeta[]; class Prefs { public: explicit Prefs(PrefService* pref_service); + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + std::string GetSeed() const; void SetSeed(const std::string& seed); std::string GetPrevSeed() const; @@ -98,6 +110,15 @@ class Prefs { int GetMigratedBookmarksVersion(); void SetMigratedBookmarksVersion(const int); + std::vector GetRecordsToResend() const; + void AddToRecordsToResend(const std::string& object_id, + std::unique_ptr meta); + void RemoveFromRecordsToResend(const std::string& object_id); + const base::DictionaryValue* GetRecordToResendMeta( + const std::string& object_id) const; + void SetRecordToResendMeta(const std::string& object_id, + std::unique_ptr meta); + void Clear(); private: diff --git a/components/brave_sync/brave_sync_service.cc b/components/brave_sync/brave_sync_service.cc index 20d180438766..a196be76303f 100644 --- a/components/brave_sync/brave_sync_service.cc +++ b/components/brave_sync/brave_sync_service.cc @@ -1,10 +1,10 @@ -/* 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 2019 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.h" -#include "base/command_line.h" -#include "brave/common/brave_switches.h" #include "brave/components/brave_sync/brave_sync_service_observer.h" namespace brave_sync { @@ -20,11 +20,4 @@ void BraveSyncService::RemoveObserver(BraveSyncServiceObserver* observer) { observers_.RemoveObserver(observer); } -// static -bool BraveSyncService::is_enabled() { - const base::CommandLine& command_line = - *base::CommandLine::ForCurrentProcess(); - return !command_line.HasSwitch(switches::kDisableBraveSync); -} - } // namespace brave_sync diff --git a/components/brave_sync/brave_sync_service.h b/components/brave_sync/brave_sync_service.h index a4e7c24dd586..325f4bb58891 100644 --- a/components/brave_sync/brave_sync_service.h +++ b/components/brave_sync/brave_sync_service.h @@ -1,15 +1,16 @@ -/* 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/. */ -#ifndef BRAVE_COMPONENTS_SYNC_BRAVE_SYNC_SERVICE_H_ -#define BRAVE_COMPONENTS_SYNC_BRAVE_SYNC_SERVICE_H_ +/* Copyright 2019 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/. */ +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_H_ + +#include #include #include "base/macros.h" #include "base/observer_list.h" -#include "components/bookmarks/browser/bookmark_storage.h" -#include "components/keyed_service/core/keyed_service.h" #include "extensions/buildflags/buildflags.h" class Profile; @@ -21,14 +22,10 @@ class BraveSyncServiceObserver; class Settings; class SyncDevices; -bookmarks::BookmarkPermanentNodeList -LoadExtraNodes(bookmarks::LoadExtraCallback callback, int64_t* next_node_id); -bool IsSyncManagedNode(const bookmarks::BookmarkPermanentNode* node); - -class BraveSyncService : public KeyedService { +class BraveSyncService { public: BraveSyncService(); - ~BraveSyncService() override; + virtual ~BraveSyncService(); typedef base::Callback, std::unique_ptr)> @@ -55,10 +52,8 @@ class BraveSyncService : public KeyedService { void AddObserver(BraveSyncServiceObserver* observer); void RemoveObserver(BraveSyncServiceObserver* observer); - static bool is_enabled(); - #if BUILDFLAG(ENABLE_EXTENSIONS) - virtual BraveSyncClient* GetSyncClient() = 0; + virtual BraveSyncClient* GetBraveSyncClient() = 0; #endif @@ -71,4 +66,4 @@ class BraveSyncService : public KeyedService { } // namespace brave_sync -#endif // BRAVE_COMPONENTS_SYNC_BRAVE_SYNC_SERVICE_H_ +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_H_ diff --git a/components/brave_sync/brave_sync_service_factory.h b/components/brave_sync/brave_sync_service_factory.h deleted file mode 100644 index 421286942045..000000000000 --- a/components/brave_sync/brave_sync_service_factory.h +++ /dev/null @@ -1,46 +0,0 @@ -/* 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/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_FACTORY_H_ -#define BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class Profile; - -namespace brave_sync { - -class BraveSyncService; - -class BraveSyncServiceFactory : public BrowserContextKeyedServiceFactory { - public: - static BraveSyncService* GetForProfile(Profile* profile); - static BraveSyncService* GetForBrowserContext( - content::BrowserContext* context); - - static BraveSyncServiceFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits; - - BraveSyncServiceFactory(); - ~BraveSyncServiceFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - void RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) override; - content::BrowserContext* GetBrowserContextToUse( - content::BrowserContext* context) const override; - bool ServiceIsNULLWhileTesting() const override; - - DISALLOW_COPY_AND_ASSIGN(BraveSyncServiceFactory); -}; - -} // namespace brave_sync - -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_FACTORY_H_ diff --git a/components/brave_sync/brave_sync_service_impl.cc b/components/brave_sync/brave_sync_service_impl.cc deleted file mode 100644 index 1117ea656ed1..000000000000 --- a/components/brave_sync/brave_sync_service_impl.cc +++ /dev/null @@ -1,713 +0,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" -#include "brave/components/brave_sync/brave_sync_prefs.h" -#include "brave/components/brave_sync/brave_sync_service_observer.h" -#include "brave/components/brave_sync/client/bookmark_change_processor.h" -#include "brave/components/brave_sync/client/brave_sync_client_impl.h" -#include "brave/components/brave_sync/sync_devices.h" -#include "brave/components/brave_sync/jslib_const.h" -#include "brave/components/brave_sync/jslib_messages.h" -#include "brave/components/brave_sync/settings.h" -#include "brave/components/brave_sync/tools.h" -#include "brave/components/brave_sync/values_conv.h" -#include "chrome/browser/profiles/profile.h" -#include "content/public/browser/browser_task_traits.h" -#include "content/public/browser/browser_thread.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "net/base/network_interfaces.h" - -namespace brave_sync { - -namespace { - -RecordsListPtr CreateDeviceCreationRecordExtension( - const std::string& deviceName, - const std::string& objectId, - const jslib::SyncRecord::Action &action, - const std::string& deviceId) { - RecordsListPtr records = std::make_unique(); - - SyncRecordPtr record = std::make_unique(); - - record->action = action; - record->deviceId = deviceId; - record->objectId = objectId; - record->objectData = jslib_const::SyncObjectData_DEVICE; // "device" - - std::unique_ptr device = std::make_unique(); - device->name = deviceName; - record->SetDevice(std::move(device)); - - records->emplace_back(std::move(record)); - - return records; -} - -SyncRecordPtr PrepareResolvedDevice( - SyncDevice* device, - int action) { - auto record = std::make_unique(); - - record->action = ConvertEnum(action, - brave_sync::jslib::SyncRecord::Action::A_MIN, - brave_sync::jslib::SyncRecord::Action::A_MAX, - brave_sync::jslib::SyncRecord::Action::A_INVALID); - record->deviceId = device->device_id_; - record->objectId = device->object_id_; - record->objectData = jslib_const::SyncObjectData_DEVICE; // "device" - - std::unique_ptr device_record = - std::make_unique(); - device_record->name = device->name_; - record->SetDevice(std::move(device_record)); - - return record; -} - -} // namespace - -BraveSyncServiceImpl::BraveSyncServiceImpl(Profile* profile) : - sync_client_(BraveSyncClient::Create(this, profile)), - sync_initialized_(false), - sync_words_(std::string()), - profile_(profile), - sync_prefs_(new brave_sync::prefs::Prefs(profile->GetPrefs())), - bookmark_change_processor_(BookmarkChangeProcessor::Create( - profile, - sync_client_.get(), - sync_prefs_.get())), - timer_(std::make_unique()), - unsynced_send_interval_(base::TimeDelta::FromMinutes(60)) { - // Moniter syncs prefs required in GetSettingsAndDevices - profile_pref_change_registrar_.Init(profile->GetPrefs()); - profile_pref_change_registrar_.Add( - prefs::kSyncEnabled, - base::Bind(&BraveSyncServiceImpl::OnSyncPrefsChanged, - base::Unretained(this))); - profile_pref_change_registrar_.Add( - prefs::kSyncDeviceName, - base::Bind(&BraveSyncServiceImpl::OnSyncPrefsChanged, - base::Unretained(this))); - profile_pref_change_registrar_.Add( - prefs::kSyncDeviceList, - base::Bind(&BraveSyncServiceImpl::OnSyncPrefsChanged, - base::Unretained(this))); - profile_pref_change_registrar_.Add( - prefs::kSyncBookmarksEnabled, - base::Bind(&BraveSyncServiceImpl::OnSyncPrefsChanged, - base::Unretained(this))); - profile_pref_change_registrar_.Add( - prefs::kSyncSiteSettingsEnabled, - base::Bind(&BraveSyncServiceImpl::OnSyncPrefsChanged, - base::Unretained(this))); - profile_pref_change_registrar_.Add( - prefs::kSyncHistoryEnabled, - base::Bind(&BraveSyncServiceImpl::OnSyncPrefsChanged, - base::Unretained(this))); - - if (!sync_prefs_->GetSeed().empty() && - !sync_prefs_->GetThisDeviceName().empty()) { - sync_configured_ = true; - } -} - -BraveSyncServiceImpl::~BraveSyncServiceImpl() { -} - -BraveSyncClient* BraveSyncServiceImpl::GetSyncClient() { - return sync_client_.get(); -} - -bool BraveSyncServiceImpl::IsSyncConfigured() { - return sync_configured_; -} - -bool BraveSyncServiceImpl::IsSyncInitialized() { - return sync_initialized_; -} - -void BraveSyncServiceImpl::Shutdown() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - bookmark_change_processor_->Stop(); - - StopLoop(); -} - -void BraveSyncServiceImpl::OnSetupSyncHaveCode(const std::string& sync_words, - const std::string& device_name) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - if (sync_words.empty()) { - OnSyncSetupError("ERR_SYNC_WRONG_WORDS"); - return; - } - - if (initializing_) { - NotifyLogMessage("currently initializing"); - return; - } - - if (IsSyncConfigured()) { - NotifyLogMessage("already configured"); - return; - } - - SetDeviceName(device_name); - initializing_ = true; - - sync_prefs_->SetSyncEnabled(true); - sync_words_ = sync_words; -} - -void BraveSyncServiceImpl::OnSetupSyncNewToSync( - const std::string& device_name) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - if (initializing_) { - NotifyLogMessage("currently initializing"); - return; - } - - if (IsSyncConfigured()) { - NotifyLogMessage("already configured"); - return; - } - - sync_words_.clear(); // If the previous attempt was connect to sync chain - // and failed to receive save-init-data - SetDeviceName(device_name); - initializing_ = true; - - sync_prefs_->SetSyncEnabled(true); -} - -void BraveSyncServiceImpl::OnDeleteDevice(const std::string& device_id) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - auto sync_devices = sync_prefs_->GetSyncDevices(); - - const SyncDevice *device = sync_devices->GetByDeviceId(device_id); - if (device) { - const std::string device_name = device->name_; - const std::string object_id = device->object_id_; - SendDeviceSyncRecord( - jslib::SyncRecord::Action::A_DELETE, device_name, device_id, object_id); - } -} - -void BraveSyncServiceImpl::OnResetSync() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - auto sync_devices = sync_prefs_->GetSyncDevices(); - - if (sync_devices->size() == 0) { - // Fail safe option - VLOG(2) << "[Sync] " << __func__ << " unexpected zero device size"; - ResetSyncInternal(); - } 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(); - OnDeleteDevice(device_id); - } -} - -void BraveSyncServiceImpl::GetSettingsAndDevices( - const GetSettingsAndDevicesCallback& callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - auto settings = sync_prefs_->GetBraveSyncSettings(); - auto devices = sync_prefs_->GetSyncDevices(); - callback.Run(std::move(settings), std::move(devices)); -} - -void BraveSyncServiceImpl::GetSyncWords() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - // Ask sync client - DCHECK(sync_client_); - std::string seed = sync_prefs_->GetSeed(); - sync_client_->NeedSyncWords(seed); -} - -std::string BraveSyncServiceImpl::GetSeed() { - return sync_prefs_->GetSeed(); -} - -void BraveSyncServiceImpl::OnSetSyncEnabled(const bool sync_this_device) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - sync_prefs_->SetSyncEnabled(sync_this_device); -} - -void BraveSyncServiceImpl::OnSetSyncBookmarks(const bool sync_bookmarks) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - sync_prefs_->SetSyncBookmarksEnabled(sync_bookmarks); -} - -void BraveSyncServiceImpl::OnSetSyncBrowsingHistory( - const bool sync_browsing_history) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - sync_prefs_->SetSyncHistoryEnabled(sync_browsing_history); -} - -void BraveSyncServiceImpl::OnSetSyncSavedSiteSettings( - const bool sync_saved_site_settings) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - sync_prefs_->SetSyncSiteSettingsEnabled(sync_saved_site_settings); -} - -// SyncLibToBrowserHandler overrides -void BraveSyncServiceImpl::BackgroundSyncStarted(bool startup) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (startup) - bookmark_change_processor_->Start(); - - StartLoop(); -} - -void BraveSyncServiceImpl::BackgroundSyncStopped(bool shutdown) { - if (shutdown) - Shutdown(); - else - StopLoop(); -} - -void BraveSyncServiceImpl::OnSyncDebug(const std::string& message) { - NotifyLogMessage(message); -} - -void BraveSyncServiceImpl::OnSyncSetupError(const std::string& error) { - if (initializing_) { - sync_prefs_->Clear(); - initializing_ = false; - } - NotifySyncSetupError(error); -} - -void BraveSyncServiceImpl::OnGetInitData(const std::string& sync_version) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - Uint8Array seed; - if (!sync_words_.empty()) { - VLOG(1) << "[Brave Sync] Init from sync words"; - } else if (!sync_prefs_->GetSeed().empty()) { - seed = Uint8ArrayFromString(sync_prefs_->GetSeed()); - VLOG(1) << "[Brave Sync] Init from prefs"; - } else { - VLOG(1) << "[Brave Sync] Init new chain"; - } - - Uint8Array device_id; - if (!sync_prefs_->GetThisDeviceId().empty()) { - device_id = Uint8ArrayFromString(sync_prefs_->GetThisDeviceId()); - VLOG(1) << "[Brave Sync] Init device id from prefs: " << - StrFromUint8Array(device_id); - } else { - VLOG(1) << "[Brave Sync] Init empty device id"; - } - - DCHECK(!sync_version.empty()); - // TODO(bridiver) - this seems broken because using the version we get back - // from the server (currently v1.4.2) causes things to break. What is the - // the point of having this value? - sync_prefs_->SetApiVersion("0"); - - brave_sync::client_data::Config config; - config.api_version = sync_prefs_->GetApiVersion(); - config.server_url = "https://sync.brave.com"; - config.debug = true; - sync_client_->SendGotInitData(seed, device_id, config, sync_words_); -} - -void BraveSyncServiceImpl::OnSaveInitData(const Uint8Array& seed, - const Uint8Array& device_id) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - DCHECK(!sync_initialized_); - // If we are here and initializing_ is false, we have came - // not from OnSetupSyncNewToSync or OnSetupSyncHaveCode. - // One case is we put wrong code words and then restarted before cleared - // kSyncEnabled pref. This should not happen. - DCHECK(initializing_); - - 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) { // 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 { - // 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); - - sync_configured_ = true; - - sync_prefs_->SetSyncBookmarksEnabled(true); - // TODO(bridiver) - re-enable these when we add history, site settings - sync_prefs_->SetSyncSiteSettingsEnabled(false); - sync_prefs_->SetSyncHistoryEnabled(false); - - initializing_ = false; -} - -void BraveSyncServiceImpl::OnSyncReady() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - const std::string bookmarks_base_order = sync_prefs_->GetBookmarksBaseOrder(); - if (bookmarks_base_order.empty()) { - std::string platform = tools::GetPlatformName(); - sync_client_->SendGetBookmarksBaseOrder(sync_prefs_->GetThisDeviceId(), - platform); - // OnSyncReady will be called by OnSaveBookmarksBaseOrder - return; - } - - DCHECK(false == sync_initialized_); - sync_initialized_ = true; - - // fetch the records - RequestSyncData(); -} - -void BraveSyncServiceImpl::OnGetExistingObjects( - const std::string& category_name, - std::unique_ptr records, - const base::Time &last_record_time_stamp, - const bool is_truncated) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // TODO(bridiver) - what do we do with is_truncated ? - // It appears to be ignored in b-l - if (!tools::IsTimeEmpty(last_record_time_stamp)) { - sync_prefs_->SetLatestRecordTime(last_record_time_stamp); - } - - if (category_name == jslib_const::kBookmarks) { - auto records_and_existing_objects = - std::make_unique(); - bookmark_change_processor_->GetAllSyncData( - *records.get(), records_and_existing_objects.get()); - sync_client_->SendResolveSyncRecords( - category_name, std::move(records_and_existing_objects)); - } else if (category_name == brave_sync::jslib_const::kPreferences) { - auto existing_records = PrepareResolvedPreferences(*records.get()); - sync_client_->SendResolveSyncRecords( - category_name, std::move(existing_records)); - } -} - -void BraveSyncServiceImpl::OnResolvedSyncRecords( - const std::string& category_name, - std::unique_ptr records) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - if (category_name == brave_sync::jslib_const::kPreferences) { - OnResolvedPreferences(*records.get()); - } else if (category_name == brave_sync::jslib_const::kBookmarks) { - bookmark_change_processor_->ApplyChangesFromSyncModel(*records.get()); - bookmark_change_processor_->SendUnsynced(unsynced_send_interval_); - } else if (category_name == brave_sync::jslib_const::kHistorySites) { - NOTIMPLEMENTED(); - } -} - -std::unique_ptr -BraveSyncServiceImpl::PrepareResolvedPreferences(const RecordsList& records) { - auto sync_devices = sync_prefs_->GetSyncDevices(); - - auto records_and_existing_objects = - std::make_unique(); - - for (const SyncRecordPtr& record : records) { - auto resolved_record = std::make_unique(); - resolved_record->first = jslib::SyncRecord::Clone(*record); - auto* device = sync_devices->GetByObjectId(record->objectId); - if (device) - resolved_record->second = PrepareResolvedDevice(device, record->action); - records_and_existing_objects->emplace_back(std::move(resolved_record)); - } - - return records_and_existing_objects; -} - -void BraveSyncServiceImpl::OnResolvedPreferences(const RecordsList& records) { - const std::string this_device_id = sync_prefs_->GetThisDeviceId(); - bool this_device_deleted = false; - bool contains_only_one_device = false; - - auto sync_devices = sync_prefs_->GetSyncDevices(); - for (const auto &record : records) { - DCHECK(record->has_device() || record->has_sitesetting()); - if (record->has_device()) { - bool actually_merged = false; - sync_devices->Merge( - SyncDevice(record->GetDevice().name, - record->objectId, - record->deviceId, - record->syncTimestamp.ToJsTime()), - record->action, - &actually_merged); - this_device_deleted = this_device_deleted || - (record->deviceId == this_device_id && - record->action == jslib::SyncRecord::Action::A_DELETE && - actually_merged); - contains_only_one_device = sync_devices->size() < 2 && - record->action == jslib::SyncRecord::Action::A_DELETE && - actually_merged; - } - } // for each device - - sync_prefs_->SetSyncDevices(*sync_devices); - - if (this_device_deleted) { - ResetSyncInternal(); - } 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) { - if (pref == prefs::kSyncEnabled) { - sync_client_->OnSyncEnabledChanged(); - if (!sync_prefs_->GetSyncEnabled()) - sync_initialized_ = false; - } - NotifySyncStateChanged(); -} - -void BraveSyncServiceImpl::OnDeletedSyncUser() { - NOTIMPLEMENTED(); -} - -void BraveSyncServiceImpl::OnDeleteSyncSiteSettings() { - NOTIMPLEMENTED(); -} - -void BraveSyncServiceImpl::OnSaveBookmarksBaseOrder(const std::string& order) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(!order.empty()); - sync_prefs_->SetBookmarksBaseOrder(order); - OnSyncReady(); -} - -void BraveSyncServiceImpl::OnSaveBookmarkOrder(const std::string& object_id, - const std::string& order) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(!order.empty()); - bookmark_change_processor_->ApplyOrder(object_id, order); -} - -void BraveSyncServiceImpl::OnSyncWordsPrepared(const std::string& words) { - NotifyHaveSyncWords(words); -} - -// Here we query sync lib for the records after initialization (or again later) -void BraveSyncServiceImpl::RequestSyncData() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - const bool bookmarks = sync_prefs_->GetSyncBookmarksEnabled(); - const bool history = sync_prefs_->GetSyncHistoryEnabled(); - const bool preferences = sync_prefs_->GetSyncSiteSettingsEnabled(); - - if (!bookmarks && !history && !preferences) - return; - - base::Time last_fetch_time = sync_prefs_->GetLastFetchTime(); - - if (tools::IsTimeEmpty(last_fetch_time)) { - SendCreateDevice(); - } - - sync_client_->SendFetchSyncDevices(); - - if (sync_prefs_->GetSyncDevices()->size() <= 1) { - // No sense to fetch or sync bookmarks when there no at least two devices - // in chain - // Set last fetch time here because we had fetched devices at least - sync_prefs_->SetLastFetchTime(base::Time::Now()); - return; - } - - if (tools::IsTimeEmpty(last_fetch_time)) { - bookmark_change_processor_->InitialSync(); - } - - FetchSyncRecords(bookmarks, history, preferences, 1000); -} - -void BraveSyncServiceImpl::FetchSyncRecords(const bool bookmarks, - const bool history, const bool preferences, int max_records) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(bookmarks || history || preferences); - if (!(bookmarks || history || preferences)) { - return; - } - - std::vector category_names; - 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"; - } - if (bookmarks) { - category_names.push_back(kBookmarks); // "BOOKMARKS"; - } - if (preferences) { - category_names.push_back(kPreferences); // "PREFERENCES"; - } - - DCHECK(sync_client_); - sync_prefs_->SetLastFetchTime(base::Time::Now()); - - base::Time start_at_time = sync_prefs_->GetLatestRecordTime(); - sync_client_->SendFetchSyncRecords( - category_names, - start_at_time, - max_records); -} - -void BraveSyncServiceImpl::SendCreateDevice() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - std::string device_name = sync_prefs_->GetThisDeviceName(); - std::string object_id = brave_sync::tools::GenerateObjectId(); - std::string device_id = sync_prefs_->GetThisDeviceId(); - CHECK(!device_id.empty()); - - SendDeviceSyncRecord( - jslib::SyncRecord::Action::A_CREATE, - device_name, - device_id, - object_id); -} - -void BraveSyncServiceImpl::SendDeviceSyncRecord( - const int action, - const std::string& device_name, - const std::string& device_id, - const std::string& object_id) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - RecordsListPtr records = CreateDeviceCreationRecordExtension( - device_name, - object_id, - static_cast(action), - device_id); - sync_client_->SendSyncRecords( - jslib_const::SyncRecordType_PREFERENCES, *records); -} - -static const int64_t kCheckUpdatesIntervalSec = 60; - -void BraveSyncServiceImpl::StartLoop() { - timer_->Start(FROM_HERE, - base::TimeDelta::FromSeconds(kCheckUpdatesIntervalSec), - this, - &BraveSyncServiceImpl::LoopProc); -} - -void BraveSyncServiceImpl::StopLoop() { - timer_->Stop(); -} - -void BraveSyncServiceImpl::LoopProc() { - base::CreateSingleThreadTaskRunnerWithTraits( - {content::BrowserThread::UI})->PostTask( - FROM_HERE, - base::BindOnce(&BraveSyncServiceImpl::LoopProcThreadAligned, - // the timer will always be destroyed before the service - base::Unretained(this))); -} - -void BraveSyncServiceImpl::LoopProcThreadAligned() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!sync_initialized_) { - return; - } - - RequestSyncData(); -} - -void BraveSyncServiceImpl::NotifyLogMessage(const std::string& message) { - DLOG(INFO) << message; -} - -void BraveSyncServiceImpl::NotifySyncSetupError(const std::string& error) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - for (auto& observer : observers_) - observer.OnSyncSetupError(this, error); -} - -void BraveSyncServiceImpl::NotifySyncStateChanged() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - for (auto& observer : observers_) - observer.OnSyncStateChanged(this); -} - -void BraveSyncServiceImpl::NotifyHaveSyncWords( - const std::string& sync_words) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - for (auto& observer : observers_) - 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); -} - -void BraveSyncServiceImpl::SetDeviceName(const std::string& name) { - if (name.empty()) { - std::string hostname = net::GetHostName(); - if (hostname.empty()) { -#if defined(OS_MACOSX) - hostname = std::string("Mac Desktop"); -#elif defined(OS_LINUX) - hostname = std::string("Linux Desktop"); -#elif defined(OS_WIN) - hostname = std::string("Windows Desktop"); -#endif - } - sync_prefs_->SetThisDeviceName(hostname); - } else { - sync_prefs_->SetThisDeviceName(name); - } -} - -} // namespace brave_sync diff --git a/components/brave_sync/brave_sync_service_impl.h b/components/brave_sync/brave_sync_service_impl.h deleted file mode 100644 index f458af09d20b..000000000000 --- a/components/brave_sync/brave_sync_service_impl.h +++ /dev/null @@ -1,217 +0,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/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_IMPL_H_ -#define BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_IMPL_H_ - -#include -#include -#include - -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "base/time/time.h" -#include "brave/components/brave_sync/brave_sync_service.h" -#include "brave/components/brave_sync/client/brave_sync_client.h" -#include "components/prefs/pref_change_registrar.h" - -FORWARD_DECLARE_TEST(BraveSyncServiceTest, BookmarkAdded); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, BookmarkDeleted); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, GetSyncWords); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, GetSeed); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnDeleteDevice); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnResetSync); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, ClientOnGetInitData); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnGetInitData); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSaveBookmarksBaseOrder); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncPrefsChanged); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncDebug); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncReadyAlreadyWithSync); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnSyncReadyNewToSync); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, OnGetExistingObjects); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, BackgroundSyncStarted); -FORWARD_DECLARE_TEST(BraveSyncServiceTest, BackgroundSyncStopped); - -class BraveSyncServiceTest; - -namespace base { -class RepeatingTimer; -} - -namespace brave_sync { - -class SyncDevices; -class Settings; -class BookmarkChangeProcessor; - -namespace prefs { -class Prefs; -} // namespace prefs - -using SendDeviceSyncRecordCallback = base::OnceCallback; - -class BraveSyncServiceImpl - : public BraveSyncService, - public SyncMessageHandler { - public: - explicit BraveSyncServiceImpl(Profile *profile); - ~BraveSyncServiceImpl() override; - - // KeyedService overrides - void Shutdown() override; - - // BraveSyncService messages from UI - void OnSetupSyncHaveCode(const std::string& sync_words, - const std::string& device_name) override; - void OnSetupSyncNewToSync(const std::string& device_name) override; - void OnDeleteDevice(const std::string& device_id) override; - void OnResetSync() override; - void GetSyncWords() override; - std::string GetSeed() override; - void OnSetSyncEnabled(const bool sync_this_device) override; - void OnSetSyncBookmarks(const bool sync_bookmarks) override; - void OnSetSyncBrowsingHistory(const bool sync_browsing_history) override; - void OnSetSyncSavedSiteSettings(const bool sync_saved_site_settings) override; - - void GetSettingsAndDevices( - const GetSettingsAndDevicesCallback& callback) override; - - bool IsSyncConfigured(); - bool IsSyncInitialized(); - - BraveSyncClient* GetSyncClient() override; - - private: - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, BookmarkAdded); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, BookmarkDeleted); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, GetSyncWords); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, GetSeed); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnDeleteDevice); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, - OnDeleteDeviceWhenSelfDeleted); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnResetSync); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, ClientOnGetInitData); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSaveBookmarksBaseOrder); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnGetInitData); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncPrefsChanged); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncDebug); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncReadyAlreadyWithSync); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnSyncReadyNewToSync); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, OnGetExistingObjects); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, BackgroundSyncStarted); - FRIEND_TEST_ALL_PREFIXES(::BraveSyncServiceTest, BackgroundSyncStopped); - friend class ::BraveSyncServiceTest; - - // SyncMessageHandler overrides - void BackgroundSyncStarted(bool startup) override; - void BackgroundSyncStopped(bool shutdown) override; - void OnSyncDebug(const std::string& message) override; - void OnSyncSetupError(const std::string& error) override; - void OnGetInitData(const std::string& sync_version) override; - void OnSaveInitData(const Uint8Array& seed, - const Uint8Array& device_id) override; - void OnSyncReady() override; - void OnGetExistingObjects(const std::string& category_name, - std::unique_ptr records, - const base::Time &last_record_time_stamp, - const bool is_truncated) override; - void OnResolvedSyncRecords(const std::string& category_name, - std::unique_ptr records) override; - void OnDeletedSyncUser() override; - void OnDeleteSyncSiteSettings() override; - void OnSaveBookmarksBaseOrder(const std::string& order) override; - void OnSaveBookmarkOrder(const std::string& object_id, - const std::string& order) override; - void OnSyncWordsPrepared(const std::string& words) override; - - void OnResolvedHistorySites(const RecordsList &records); - void OnResolvedPreferences(const RecordsList &records); - std::unique_ptr PrepareResolvedPreferences( - const RecordsList& records); - - void OnSyncPrefsChanged(const std::string& pref); - - // Other private methods - void RequestSyncData(); - void FetchSyncRecords(const bool bookmarks, const bool history, - const bool preferences, int max_records); - - void SendCreateDevice(); - void SendDeviceSyncRecord( - const int action, - const std::string& device_name, - const std::string& device_id, - const std::string& object_id); - - void SetUpdateDeleteDeviceName_Ext( - const std::string& action, - const std::string& deviceName, - const std::string& deviceId, - const std::string& objectId); - - void StartLoop(); - void StopLoop(); - void LoopProc(); - void LoopProcThreadAligned(); - - void GetExistingHistoryObjects( - const RecordsList &records, - const base::Time &last_record_time_stamp, - const bool is_truncated); - - void NotifyLogMessage(const std::string& message); - void NotifySyncSetupError(const std::string& error); - void NotifySyncStateChanged(); - void NotifyHaveSyncWords(const std::string& sync_words); - - void ResetSyncInternal(); - - void SetDeviceName(const std::string& name); - - std::unique_ptr sync_client_; - - // True when is in active sync chain - bool sync_configured_ = false; - // True if we have received SyncReady from JS lib - bool sync_initialized_ = false; - - // Prevent two sequential calls OnSetupSyncHaveCode or OnSetupSyncNewToSync - // while being initializing - bool initializing_ = false; - - bool reseting_ = false; - - std::string sync_words_; - - std::unique_ptr settings_; - - Profile* profile_; - std::unique_ptr sync_prefs_; - - std::unique_ptr bookmark_change_processor_; - // Moment when FETCH_SYNC_RECORDS was sent, - // will be saved on GET_EXISTING_OBJECTS to be sure request was processed - base::Time last_time_fetch_sent_; - - std::unique_ptr timer_; - - // send unsynced records in batches - base::TimeDelta unsynced_send_interval_; - - // Registrar used to monitor the profile prefs. - PrefChangeRegistrar profile_pref_change_registrar_; - - DISALLOW_COPY_AND_ASSIGN(BraveSyncServiceImpl); -}; - -} // namespace brave_sync - -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_SERVICE_IMPL_H_ diff --git a/components/brave_sync/brave_sync_service_unittest.cc b/components/brave_sync/brave_sync_service_unittest.cc index 9968e2c69260..459f6f9cbeeb 100644 --- a/components/brave_sync/brave_sync_service_unittest.cc +++ b/components/brave_sync/brave_sync_service_unittest.cc @@ -3,29 +3,35 @@ * 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 +#include +#include + #include "base/files/scoped_temp_dir.h" #include "base/strings/utf_string_conversions.h" -#include "brave/components/brave_sync/client/bookmark_change_processor.h" +#include "brave/components/brave_sync/brave_profile_sync_service_impl.h" +#include "brave/components/brave_sync/brave_sync_prefs.h" +#include "brave/components/brave_sync/brave_sync_service.h" +#include "brave/components/brave_sync/brave_sync_service_observer.h" #include "brave/components/brave_sync/client/brave_sync_client_impl.h" #include "brave/components/brave_sync/client/client_ext_impl_data.h" -#include "brave/components/brave_sync/brave_sync_service_impl.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" -#include "brave/components/brave_sync/brave_sync_service_observer.h" #include "brave/components/brave_sync/jslib_const.h" #include "brave/components/brave_sync/jslib_messages.h" #include "brave/components/brave_sync/settings.h" #include "brave/components/brave_sync/sync_devices.h" #include "brave/components/brave_sync/test_util.h" +#include "brave/components/brave_sync/tools.h" #include "brave/components/brave_sync/values_conv.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/browser/bookmark_utils.h" #include "components/bookmarks/test/test_bookmark_client.h" #include "components/prefs/pref_service.h" +#include "components/sync/base/pref_names.h" #include "content/public/browser/network_service_instance.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "services/network/test/test_network_connection_tracker.h" #include "net/base/network_interfaces.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -70,7 +76,7 @@ // BraveSyncService SyncMessageHandler overrides // Name | Covered //------------------------------------- -// BackgroundSyncStarted | +, BraveSyncServiceTest.BookmarkAddedImpl +// BackgroundSyncStarted | N/A // BackgroundSyncStopped | + // OnSyncDebug | + // OnSyncSetupError | Need UI handler @@ -78,7 +84,7 @@ // OnSaveInitData | BraveSyncServiceTest.GetSeed // OnSyncReady | + // OnGetExistingObjects | + -// OnResolvedSyncRecords | BraveSyncServiceTest.BookmarkAddedImpl +// OnResolvedSyncRecords | N/A // OnDeletedSyncUser | N/A // OnDeleteSyncSiteSettings | N/A // OnSaveBookmarksBaseOrder | + @@ -86,20 +92,77 @@ // OnResolvedHistorySites | N/A // OnResolvedPreferences | BraveSyncServiceTest.OnDeleteDevice, // | BraveSyncServiceTest.OnResetSync -// OnSyncPrefsChanged | + +// OnBraveSyncPrefsChanged | + +using bookmarks::BookmarkModel; +using brave_sync::BraveProfileSyncServiceImpl; 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::SimpleBookmarkSyncRecord; using brave_sync::SimpleDeviceRecord; -using network::TestNetworkConnectionTracker; -using network::mojom::ConnectionType; +using brave_sync::jslib::SyncRecord; using testing::_; using testing::AtLeast; +namespace { + +const bookmarks::BookmarkNode* GetSingleNodeByUrl( + bookmarks::BookmarkModel* model, + const std::string& url) { + std::vector nodes; + model->GetNodesByURL(GURL(url), &nodes); + size_t nodes_size = nodes.size(); + CHECK_EQ(nodes_size, 1u); + const bookmarks::BookmarkNode* node = nodes.at(0); + return node; +} + +bool DevicesContains(brave_sync::SyncDevices* devices, + const std::string& id, + const std::string& name) { + DCHECK(devices); + for (const auto& device : devices->devices_) { + if (device.device_id_ == id && device.name_ == name) { + return true; + } + } + return false; +} + +MATCHER_P2(ContainsDeviceRecord, + action, + name, + "contains device sync record with params") { + for (const auto& record : arg) { + if (record->has_device()) { + const auto& device = record->GetDevice(); + if (record->action == action && device.name == name) { + return true; + } + } + } + return false; +} + +size_t g_overridden_minutes = 0; +base::Time g_overridden_now; +std::unique_ptr OverrideForMinutes( + int overridden_minutes, + const base::Time& now = base::subtle::TimeNowIgnoringOverride()) { + g_overridden_minutes = overridden_minutes; + g_overridden_now = now; + return std::make_unique( + []() { + return g_overridden_now + + base::TimeDelta::FromMinutes(g_overridden_minutes); + }, + nullptr, nullptr); +} + +} // namespace + class MockBraveSyncServiceObserver : public BraveSyncServiceObserver { public: MockBraveSyncServiceObserver() {} @@ -122,6 +185,8 @@ class BraveSyncServiceTest : public testing::Test { profile_ = brave_sync::CreateBraveSyncProfile(temp_dir_.GetPath()); EXPECT_TRUE(profile_.get() != NULL); + sync_prefs_ = std::make_unique(profile_->GetPrefs()); + // TODO(bridiver) - this is temporary until some changes are made to // to bookmark_change_processor to allow `set_for_testing` like // BraveSyncClient @@ -129,39 +194,41 @@ class BraveSyncServiceTest : public testing::Test { profile(), base::BindRepeating(&brave_sync::BuildFakeBookmarkModelForTests)); - brave_sync::BraveSyncClientImpl::set_for_testing( - new MockBraveSyncClient()); + model_ = BookmarkModelFactory::GetForBrowserContext( + Profile::FromBrowserContext(profile_.get())); + EXPECT_NE(model(), nullptr); - sync_service_ = static_cast( - brave_sync::BraveSyncServiceFactory::GetInstance()->GetForProfile( + sync_client_ = new MockBraveSyncClient(); + brave_sync::BraveSyncClientImpl::set_for_testing(sync_client_); + + sync_service_ = static_cast( + ProfileSyncServiceFactory::GetAsProfileSyncServiceForProfile( profile())); - sync_client_ = - static_cast(sync_service_->GetSyncClient()); + EXPECT_EQ(sync_client_, sync_service_->GetBraveSyncClient()); observer_.reset(new MockBraveSyncServiceObserver); - sync_service_->AddObserver(observer_.get()); + sync_service_->BraveSyncService::AddObserver(observer_.get()); EXPECT_TRUE(sync_service_ != NULL); - - // TestNetworkConnectionTracker::CreateInstance has been called in - // TestingBrowserProcess - TestNetworkConnectionTracker* tracker = - TestNetworkConnectionTracker::GetInstance(); - tracker->SetConnectionType(ConnectionType::CONNECTION_UNKNOWN); } void TearDown() override { - sync_service_->RemoveObserver(observer_.get()); + sync_service_->BraveSyncService::RemoveObserver(observer_.get()); // this will also trigger a shutdown of the brave sync service + sync_service_->Shutdown(); + sync_prefs_.reset(); profile_.reset(); } - void BookmarkAddedImpl(); - Profile* profile() { return profile_.get(); } - BraveSyncServiceImpl* sync_service() { return sync_service_; } + BraveProfileSyncServiceImpl* sync_service() { return sync_service_; } MockBraveSyncClient* sync_client() { return sync_client_; } + BookmarkModel* model() { return model_; } MockBraveSyncServiceObserver* observer() { return observer_.get(); } + brave_sync::prefs::Prefs* brave_sync_prefs() { + return sync_service_->brave_sync_prefs_.get(); + } + syncer::SyncPrefs* sync_prefs() { return sync_prefs_.get(); } private: // Need this as a very first member to run tests in UI thread @@ -170,8 +237,10 @@ class BraveSyncServiceTest : public testing::Test { content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr profile_; - BraveSyncServiceImpl* sync_service_; + BraveProfileSyncServiceImpl* sync_service_; MockBraveSyncClient* sync_client_; + BookmarkModel* model_; // Not owns + std::unique_ptr sync_prefs_; std::unique_ptr observer_; base::ScopedTempDir temp_dir_; @@ -185,8 +254,8 @@ TEST_F(BraveSyncServiceTest, SetSyncEnabled) { sync_service()->OnSetSyncEnabled(true); EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncEnabled)); - EXPECT_FALSE(sync_service()->IsSyncInitialized()); - EXPECT_FALSE(sync_service()->IsSyncConfigured()); + EXPECT_FALSE(sync_service()->IsBraveSyncInitialized()); + EXPECT_FALSE(sync_service()->IsBraveSyncConfigured()); } TEST_F(BraveSyncServiceTest, SetSyncDisabled) { @@ -201,60 +270,16 @@ TEST_F(BraveSyncServiceTest, SetSyncDisabled) { sync_service()->OnSetSyncEnabled(false); EXPECT_FALSE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncEnabled)); - EXPECT_FALSE(sync_service()->IsSyncInitialized()); - EXPECT_FALSE(sync_service()->IsSyncConfigured()); + EXPECT_FALSE(sync_service()->IsBraveSyncInitialized()); + EXPECT_FALSE(sync_service()->IsBraveSyncConfigured()); } TEST_F(BraveSyncServiceTest, IsSyncConfiguredOnNewProfile) { - EXPECT_FALSE(sync_service()->IsSyncConfigured()); + EXPECT_FALSE(sync_service()->IsBraveSyncConfigured()); } TEST_F(BraveSyncServiceTest, IsSyncInitializedOnNewProfile) { - EXPECT_FALSE(sync_service()->IsSyncInitialized()); -} - -void BraveSyncServiceTest::BookmarkAddedImpl() { - // BraveSyncService: real - // BraveSyncClient: mock - // Invoke BraveSyncService::BookmarkAdded - // Expect BraveSyncClient::SendSyncRecords invoked - EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); - EXPECT_CALL(*observer(), - OnSyncStateChanged(sync_service())).Times(AtLeast(1)); - sync_service()->OnSetupSyncNewToSync("UnitTestBookmarkAdded"); - sync_service()->BackgroundSyncStarted(true/*startup*/); - - auto* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile()); - bookmarks::AddIfNotBookmarked(bookmark_model, - GURL("https://a.com"), - base::ASCIIToUTF16("A.com - title")); - // Force service send bookmarks and fire the mock - EXPECT_CALL(*sync_client(), SendSyncRecords(_, _)).Times(1); - sync_service()->OnResolvedSyncRecords(brave_sync::jslib_const::kBookmarks, - std::make_unique()); -} - -TEST_F(BraveSyncServiceTest, BookmarkAdded) { - BookmarkAddedImpl(); -} - -TEST_F(BraveSyncServiceTest, BookmarkDeleted) { - BookmarkAddedImpl(); - auto* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile()); - - // And just now can actually test delete - std::vector nodes; - bookmarks::GetMostRecentlyAddedEntries(bookmark_model, 1, &nodes); - ASSERT_EQ(nodes.size(), 1u); - ASSERT_NE(nodes.at(0), nullptr); - // 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 - // <= BraveSyncServiceImpl::OnResolvedSyncRecords - sync_service()->OnResolvedSyncRecords(brave_sync::jslib_const::kBookmarks, - std::make_unique()); + EXPECT_FALSE(sync_service()->IsBraveSyncInitialized()); } TEST_F(BraveSyncServiceTest, OnSetupSyncHaveCode) { @@ -266,7 +291,7 @@ TEST_F(BraveSyncServiceTest, OnSetupSyncHaveCode) { brave_sync::prefs::kSyncEnabled)); } -TEST_F(BraveSyncServiceTest, OnSetupSyncHaveCode_EmptyDeviceName) { +TEST_F(BraveSyncServiceTest, OnSetupSyncHaveCodeEmptyDeviceName) { EXPECT_CALL(*sync_client(), OnSyncEnabledChanged); // Expecting sync state changed twice: for enabled state and for device name EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(2); @@ -286,7 +311,7 @@ TEST_F(BraveSyncServiceTest, OnSetupSyncNewToSync) { brave_sync::prefs::kSyncEnabled)); } -TEST_F(BraveSyncServiceTest, OnSetupSyncNewToSync_EmptyDeviceName) { +TEST_F(BraveSyncServiceTest, OnSetupSyncNewToSyncEmptyDeviceName) { EXPECT_CALL(*sync_client(), OnSyncEnabledChanged); // Expecting sync state changed twice: for enabled state and for device name EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(2); @@ -357,36 +382,11 @@ TEST_F(BraveSyncServiceTest, GetSeed) { // Service gets seed from client via BraveSyncServiceImpl::OnSaveInitData const auto binary_seed = brave_sync::Uint8Array(16, 77); - EXPECT_TRUE(sync_service()->sync_prefs_->GetPrevSeed().empty()); + EXPECT_TRUE(brave_sync_prefs()->GetPrevSeed().empty()); sync_service()->OnSaveInitData(binary_seed, {0}); 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(brave_sync::SyncDevices* devices, const std::string& id, - const std::string& name) { - DCHECK(devices); - for (const auto& device : devices->devices_) { - if (device.device_id_ == id && device.name_ == name) { - return true; - } - } - return false; -} - -MATCHER_P2(ContainsDeviceRecord, action, name, - "contains device sync record with params") { - for (const auto& record : arg) { - if (record->has_device()) { - const auto& device = record->GetDevice(); - if (record->action == action && - device.name == name) { - return true; - } - } - } - return false; + EXPECT_TRUE(brave_sync_prefs()->GetPrevSeed().empty()); } TEST_F(BraveSyncServiceTest, OnDeleteDevice) { @@ -403,8 +403,8 @@ 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(); + brave_sync_prefs()->SetThisDeviceId("1"); + auto devices = brave_sync_prefs()->GetSyncDevices(); EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1")); EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2")); @@ -428,14 +428,14 @@ TEST_F(BraveSyncServiceTest, OnDeleteDevice) { EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); sync_service()->OnResolvedPreferences(resolved_records); - auto devices_final = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices_final = brave_sync_prefs()->GetSyncDevices(); EXPECT_TRUE(DevicesContains(devices_final.get(), "1", "device1")); EXPECT_TRUE(DevicesContains(devices_final.get(), "2", "device2")); EXPECT_FALSE(DevicesContains(devices_final.get(), "3", "device3")); } TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { - sync_service()->sync_prefs_->SetThisDeviceId("1"); + brave_sync_prefs()->SetThisDeviceId("1"); RecordsList records; records.push_back(SimpleDeviceRecord( SyncRecord::Action::A_CREATE, @@ -446,7 +446,7 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); sync_service()->OnResolvedPreferences(records); - auto devices = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices = brave_sync_prefs()->GetSyncDevices(); EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1")); EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2")); @@ -465,10 +465,13 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { sync_service()->OnResolvedPreferences(resolved_records); - auto devices_semi_final = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices_semi_final = brave_sync_prefs()->GetSyncDevices(); EXPECT_FALSE(DevicesContains(devices_semi_final.get(), "2", "device2")); EXPECT_TRUE(DevicesContains(devices_semi_final.get(), "1", "device1")); + // Enabled->Disabled + EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); + // Emulate sending DELETE for this device RecordsList resolved_records2; auto resolved_record2 = SyncRecord::Clone(*records.at(0)); @@ -478,14 +481,14 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenOneDevice) { sync_service()->OnResolvedPreferences(resolved_records2); - auto devices_final = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices_final = brave_sync_prefs()->GetSyncDevices(); EXPECT_FALSE(DevicesContains(devices_final.get(), "1", "device1")); EXPECT_FALSE(DevicesContains(devices_final.get(), "2", "device2")); - EXPECT_FALSE(sync_service()->IsSyncConfigured()); + EXPECT_FALSE(sync_service()->IsBraveSyncConfigured()); } TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { - sync_service()->sync_prefs_->SetThisDeviceId("1"); + brave_sync_prefs()->SetThisDeviceId("1"); RecordsList records; records.push_back(SimpleDeviceRecord( SyncRecord::Action::A_CREATE, @@ -496,7 +499,7 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); sync_service()->OnResolvedPreferences(records); - auto devices = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices = brave_sync_prefs()->GetSyncDevices(); EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1")); EXPECT_TRUE(DevicesContains(devices.get(), "2", "device2")); @@ -505,6 +508,9 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { ContainsDeviceRecord(SyncRecord::Action::A_DELETE, "device1"))).Times(1); sync_service()->OnDeleteDevice("1"); + // Enabled->Disabled + EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); + RecordsList resolved_records; auto resolved_record = SyncRecord::Clone(*records.at(0)); resolved_record->action = SyncRecord::Action::A_DELETE; @@ -513,11 +519,11 @@ TEST_F(BraveSyncServiceTest, OnDeleteDeviceWhenSelfDeleted) { EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(3); sync_service()->OnResolvedPreferences(resolved_records); - auto devices_final = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices_final = brave_sync_prefs()->GetSyncDevices(); EXPECT_FALSE(DevicesContains(devices_final.get(), "1", "device1")); EXPECT_FALSE(DevicesContains(devices_final.get(), "2", "device2")); - EXPECT_FALSE(sync_service()->IsSyncConfigured()); + EXPECT_FALSE(sync_service()->IsBraveSyncConfigured()); } TEST_F(BraveSyncServiceTest, OnResetSync) { @@ -527,7 +533,7 @@ TEST_F(BraveSyncServiceTest, OnResetSync) { sync_service()->OnSetupSyncNewToSync("this_device"); EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncEnabled)); - sync_service()->sync_prefs_->SetThisDeviceId("0"); + brave_sync_prefs()->SetThisDeviceId("0"); RecordsList records; records.push_back(SimpleDeviceRecord( @@ -539,11 +545,17 @@ TEST_F(BraveSyncServiceTest, OnResetSync) { sync_service()->OnResolvedPreferences(records); - auto devices = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices = brave_sync_prefs()->GetSyncDevices(); EXPECT_TRUE(DevicesContains(devices.get(), "0", "this_device")); EXPECT_TRUE(DevicesContains(devices.get(), "1", "device1")); + EXPECT_CALL(*sync_client(), + SendSyncRecords("PREFERENCES", + ContainsDeviceRecord(SyncRecord::Action::A_DELETE, + "this_device"))) + .Times(1); + sync_service()->OnResetSync(); RecordsList resolved_records; auto resolved_record = SyncRecord::Clone(*records.at(0)); @@ -551,7 +563,7 @@ TEST_F(BraveSyncServiceTest, OnResetSync) { resolved_records.push_back(std::move(resolved_record)); sync_service()->OnResolvedPreferences(resolved_records); - auto devices_final = sync_service()->sync_prefs_->GetSyncDevices(); + auto devices_final = brave_sync_prefs()->GetSyncDevices(); EXPECT_FALSE(DevicesContains(devices_final.get(), "0", "this_device")); EXPECT_FALSE(DevicesContains(devices_final.get(), "1", "device1")); @@ -580,8 +592,12 @@ TEST_F(BraveSyncServiceTest, OnResetSync) { EXPECT_EQ(profile()->GetPrefs()->GetString( brave_sync::prefs::kSyncApiVersion), "0"); - EXPECT_FALSE(sync_service()->IsSyncInitialized()); - EXPECT_FALSE(sync_service()->IsSyncConfigured()); + EXPECT_FALSE(sync_service()->IsBraveSyncInitialized()); + EXPECT_FALSE(sync_service()->IsBraveSyncConfigured()); + + EXPECT_FALSE(sync_prefs()->IsSyncRequested()); + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(syncer::prefs::kSyncBookmarks)); } TEST_F(BraveSyncServiceTest, OnSetSyncBookmarks) { @@ -589,12 +605,17 @@ TEST_F(BraveSyncServiceTest, OnSetSyncBookmarks) { brave_sync::prefs::kSyncBookmarksEnabled)); EXPECT_CALL(*observer(), OnSyncStateChanged).Times(1); sync_service()->OnSetSyncBookmarks(true); + EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(syncer::prefs::kSyncBookmarks)); EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncBookmarksEnabled)); EXPECT_CALL(*observer(), OnSyncStateChanged).Times(1); sync_service()->OnSetSyncBookmarks(false); EXPECT_FALSE(profile()->GetPrefs()->GetBoolean( brave_sync::prefs::kSyncBookmarksEnabled)); + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(syncer::prefs::kSyncBookmarks)); + EXPECT_CALL(*observer(), OnSyncStateChanged).Times(0); + sync_service()->OnSetSyncBookmarks(false); } TEST_F(BraveSyncServiceTest, OnSetSyncBrowsingHistory) { @@ -629,61 +650,65 @@ TEST_F(BraveSyncServiceTest, OnGetInitData) { } TEST_F(BraveSyncServiceTest, OnSaveBookmarksBaseOrder) { + EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); + // kSyncEnabled and kSyncBookmarksEnabled + EXPECT_CALL(*observer(), OnSyncStateChanged).Times(2); + sync_service()->OnSetSyncEnabled(true); sync_service()->OnSaveBookmarksBaseOrder("1.1."); EXPECT_EQ(profile()->GetPrefs()->GetString( brave_sync::prefs::kSyncBookmarksBaseOrder), "1.1."); + // Permanent node order + std::string order; + model()->bookmark_bar_node()->GetMetaInfo("order", &order); + EXPECT_EQ(order, "1.1.1"); + order.clear(); + model()->other_node()->GetMetaInfo("order", &order); + EXPECT_EQ(order, "1.1.2"); + EXPECT_EQ(brave_sync_prefs()->GetMigratedBookmarksVersion(), 2); } -TEST_F(BraveSyncServiceTest, OnSyncPrefsChanged) { +TEST_F(BraveSyncServiceTest, OnBraveSyncPrefsChanged) { EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); EXPECT_CALL(*observer(), OnSyncStateChanged); - sync_service()->OnSyncPrefsChanged(brave_sync::prefs::kSyncEnabled); + sync_service()->OnBraveSyncPrefsChanged(brave_sync::prefs::kSyncEnabled); } -TEST_F(BraveSyncServiceTest, OnSyncReadyAlreadyWithSync) { - EXPECT_FALSE(sync_service()->IsSyncInitialized()); +TEST_F(BraveSyncServiceTest, StartSyncNonDeviceRecords) { + EXPECT_FALSE(sync_service()->IsBraveSyncInitialized()); + sync_service()->OnSetSyncEnabled(true); profile()->GetPrefs()->SetString( brave_sync::prefs::kSyncBookmarksBaseOrder, "1.1."); - // OnSyncPrefsChanged => OnSyncStateChanged for - // kSyncSiteSettingsEnabled (1) and kSyncDeviceList (2) - EXPECT_CALL(*observer(), OnSyncStateChanged).Times(2); - profile()->GetPrefs()->SetBoolean( - brave_sync::prefs::kSyncSiteSettingsEnabled, true); - profile()->GetPrefs()->SetTime( - brave_sync::prefs::kSyncLastFetchTime, base::Time::Now()); - const char* devices_json = R"( - { - "devices":[ - { - "device_id":"0", - "last_active":1552993896717.0, - "name":"Device1", - "object_id":"186, 247, 230, 75, 57, 111, 76, 166, 51, 142, 217, 221, 219, 237, 229, 235" - }, - { - "device_id":"1", - "last_active":1552993909257.0, - "name":"Device2", - "object_id":"36, 138, 200, 221, 191, 81, 214, 65, 134, 48, 55, 119, 162, 93, 33, 226" - } - ] - } - )"; - - profile()->GetPrefs()->SetString( - brave_sync::prefs::kSyncDeviceList, devices_json); - EXPECT_CALL(*sync_client(), SendFetchSyncRecords).Times(1); - EXPECT_CALL(*sync_client(), SendFetchSyncDevices).Times(1); - sync_service()->OnSyncReady(); - EXPECT_TRUE(sync_service()->IsSyncInitialized()); + profile()->GetPrefs()->SetBoolean(brave_sync::prefs::kSyncBookmarksEnabled, + true); + EXPECT_FALSE( + profile()->GetPrefs()->GetBoolean(syncer::prefs::kSyncBookmarks)); + brave_sync_prefs()->SetThisDeviceId("1"); + RecordsList records; + records.push_back( + SimpleDeviceRecord(SyncRecord::Action::A_CREATE, "1", "device1")); + records.push_back( + SimpleDeviceRecord(SyncRecord::Action::A_CREATE, "2", "device2")); + EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); + sync_service()->OnResolvedPreferences(records); + EXPECT_TRUE( + !brave_sync::tools::IsTimeEmpty(sync_service()->chain_created_time_)); } TEST_F(BraveSyncServiceTest, OnSyncReadyNewToSync) { + sync_prefs()->SetSyncRequested(false); EXPECT_CALL(*observer(), OnSyncStateChanged); - profile()->GetPrefs()->SetBoolean( - brave_sync::prefs::kSyncSiteSettingsEnabled, true); EXPECT_CALL(*sync_client(), SendGetBookmarksBaseOrder).Times(1); sync_service()->OnSyncReady(); + + // simulate OnSaveBookmarksBaseOrder + profile()->GetPrefs()->SetString(brave_sync::prefs::kSyncBookmarksBaseOrder, + "1.1."); + sync_service()->OnSyncReady(); + EXPECT_TRUE(sync_prefs()->IsSyncRequested()); + + // We want to have Chromium syncer bookmarks be enabled from begin to avoid + // reaching BookmarkModelAssociator::AssociateModels + EXPECT_TRUE(profile()->GetPrefs()->GetBoolean(syncer::prefs::kSyncBookmarks)); } TEST_F(BraveSyncServiceTest, OnGetExistingObjects) { @@ -696,12 +721,169 @@ TEST_F(BraveSyncServiceTest, OnGetExistingObjects) { false); } -TEST_F(BraveSyncServiceTest, BackgroundSyncStarted) { - sync_service()->BackgroundSyncStarted(false); - EXPECT_TRUE(sync_service()->timer_->IsRunning()); +TEST_F(BraveSyncServiceTest, GetPreferredDataTypes) { + // Make sure GetPreferredDataTypes contains DEVICE_INFO which is needed for + // brave device record polling + EXPECT_TRUE(sync_service()->GetPreferredDataTypes().Has(syncer::DEVICE_INFO)); +} + +TEST_F(BraveSyncServiceTest, GetDisableReasons) { + sync_prefs()->SetManagedForTest(true); + EXPECT_EQ(sync_service()->GetDisableReasons(), + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY); + sync_service()->OnSetSyncEnabled(true); + EXPECT_EQ(sync_service()->GetDisableReasons(), + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY); + brave_sync_prefs()->SetMigratedBookmarksVersion(2); + EXPECT_EQ(sync_service()->GetDisableReasons(), + syncer::SyncService::DISABLE_REASON_NONE); + sync_service()->OnSetSyncEnabled(false); + EXPECT_TRUE(sync_service()->HasDisableReason( + syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)); } -TEST_F(BraveSyncServiceTest, BackgroundSyncStopped) { - sync_service()->BackgroundSyncStopped(false); - EXPECT_FALSE(sync_service()->timer_->IsRunning()); +TEST_F(BraveSyncServiceTest, OnSetupSyncHaveCode_Reset_SetupAgain) { + EXPECT_FALSE(sync_service()->GetResettingForTest()); + EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(1); + // Expecting sync state changed twice: for enabled state and for device name + EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(2); + sync_service()->OnSetupSyncHaveCode("word1 word2 word3", "test_device"); + EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( + brave_sync::prefs::kSyncEnabled)); + + brave_sync::Uint8Array seed + = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; + brave_sync::Uint8Array device_id = {0}; + sync_service()->OnSaveInitData(seed, device_id); + + RecordsList records; + records.push_back(SimpleDeviceRecord( + SyncRecord::Action::A_CREATE, + "0", "this_device")); + EXPECT_CALL(*observer(), OnSyncStateChanged(sync_service())).Times(1); + sync_service()->OnResolvedPreferences(records); + + auto devices = brave_sync_prefs()->GetSyncDevices(); + + ASSERT_EQ(devices->size(), 1u); + EXPECT_TRUE(DevicesContains(devices.get(), "0", "this_device")); + EXPECT_CALL(*sync_client(), SendSyncRecords("PREFERENCES", + ContainsDeviceRecord(SyncRecord::Action::A_DELETE, + "this_device"))).Times(1); + sync_service()->OnResetSync(); + // Here we have marked service as in resetting state + // Actual kSyncEnabled will go to false after receiving confirmation of + // this_device DELETE + EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( + brave_sync::prefs::kSyncEnabled)); + + EXPECT_TRUE(sync_service()->GetResettingForTest()); + + // OnSyncStateChanged actually is invoked 9 times: + // ForceCompleteReset + // ResetSyncInternal + // brave_sync::Prefs::Clear() + // device_name + // enabled => false + // bookmarks_enabled + // site_settings_enabled + // history_enabled + // device_list + // enabled => false + // OnSetupSyncHaveCode() + // device_name + // enabled => true + + // OnSyncEnabledChanged is actually invoked 3 times: + // see preference enabled in abobe list + EXPECT_CALL(*observer(), + OnSyncStateChanged(sync_service())).Times(AtLeast(1)); + EXPECT_CALL(*sync_client(), OnSyncEnabledChanged).Times(AtLeast(1)); + sync_service()->OnSetupSyncHaveCode("word1 word2 word5", "test_device"); + EXPECT_FALSE(sync_service()->GetResettingForTest()); + + EXPECT_TRUE(profile()->GetPrefs()->GetBoolean( + brave_sync::prefs::kSyncEnabled)); +} + +TEST_F(BraveSyncServiceTest, ExponentialResend) { + bookmarks::AddIfNotBookmarked(model(), GURL("https://a.com/"), + base::ASCIIToUTF16("A.com")); + // Explicitly set sync_timestamp, object_id and order because it is supposed + // to be set in syncer + auto* node = GetSingleNodeByUrl(model(), "https://a.com/"); + model()->SetNodeMetaInfo(node, "sync_timestamp", + std::to_string(base::Time::Now().ToJsTime())); + const char* record_a_object_id = + "121, 194, 37, 61, 199, 11, 166, 234, " + "214, 197, 45, 215, 241, 206, 219, 130"; + model()->SetNodeMetaInfo(node, "object_id", record_a_object_id); + const char* record_a_order = "1.1.1.1"; + model()->SetNodeMetaInfo(node, "order", record_a_order); + + brave_sync_prefs()->SetThisDeviceId("1"); + std::unique_ptr records = std::make_unique(); + records->push_back(SimpleBookmarkSyncRecord( + SyncRecord::Action::A_CREATE, record_a_object_id, "https://a.com/", + "A.com - title", record_a_order, "", + brave_sync_prefs()->GetThisDeviceId())); + + EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(1); + sync_service()->SendSyncRecords("BOOKMARKS", std::move(records)); + + EXPECT_EQ(brave_sync_prefs()->GetRecordsToResend().size(), 1u); + const base::DictionaryValue* meta = + brave_sync_prefs()->GetRecordToResendMeta(record_a_object_id); + int send_retry_number = -1; + meta->GetInteger("send_retry_number", &send_retry_number); + EXPECT_EQ(send_retry_number, 0); + double sync_timestamp = -1; + meta->GetDouble("sync_timestamp", &sync_timestamp); + EXPECT_NE(sync_timestamp, -1); + + int expected_send_retry_number = 0; + + static const std::vector exponential_waits = + brave_sync::BraveProfileSyncServiceImpl::GetExponentialWaitsForTests(); + const int max_send_retries = exponential_waits.size() - 1; + std::set should_sent_at; + for (size_t j = 0; j < exponential_waits.size(); ++j) { + should_sent_at.insert(exponential_waits[j]); + } + auto contains = [](const std::set& set, int val) { + return set.find(val) != set.end(); + }; + for (size_t i = 0; i <= exponential_waits.back(); ++i) { + auto time_override = + OverrideForMinutes(i, base::Time::FromJsTime(sync_timestamp)); + bool is_send_expected = contains(should_sent_at, i); + int expect_call_times = is_send_expected ? 1 : 0; + EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)) + .Times(expect_call_times); + sync_service()->ResendSyncRecords("BOOKMARKS"); + + if (is_send_expected) { + if (++expected_send_retry_number > max_send_retries) + expected_send_retry_number = max_send_retries; + send_retry_number = -1; + meta = brave_sync_prefs()->GetRecordToResendMeta(record_a_object_id); + meta->GetInteger("send_retry_number", &send_retry_number); + EXPECT_EQ(send_retry_number, expected_send_retry_number); + } + } + + // resolve to confirm records + RecordsList records_to_resolve; + records_to_resolve.push_back(SimpleBookmarkSyncRecord( + SyncRecord::Action::A_CREATE, record_a_object_id, "https://a.com/", + "A.com", "1.1.1.1", "", brave_sync_prefs()->GetThisDeviceId())); + auto timestamp_resolve = base::Time::Now(); + records_to_resolve.at(0)->syncTimestamp = timestamp_resolve; + brave_sync::SyncRecordAndExistingList records_and_existing_objects; + sync_service()->CreateResolveList(records_to_resolve, + &records_and_existing_objects); + + EXPECT_EQ(brave_sync_prefs()->GetRecordsToResend().size(), 0u); + EXPECT_EQ(brave_sync_prefs()->GetRecordToResendMeta(record_a_object_id), + nullptr); } diff --git a/components/brave_sync/client/bookmark_change_processor.cc b/components/brave_sync/client/bookmark_change_processor.cc deleted file mode 100644 index d5d1cf39343b..000000000000 --- a/components/brave_sync/client/bookmark_change_processor.cc +++ /dev/null @@ -1,978 +0,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/client/bookmark_change_processor.h" - -#include -#include -#include -#include -#include - -#include "base/strings/utf_string_conversions.h" -#include "brave/components/brave_sync/bookmark_order_util.h" -#include "brave/components/brave_sync/client/bookmark_node.h" -#include "brave/components/brave_sync/jslib_const.h" -#include "brave/components/brave_sync/jslib_messages.h" -#include "brave/components/brave_sync/tools.h" -#include "chrome/browser/bookmarks/bookmark_model_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "components/bookmarks/browser/bookmark_storage.h" -#include "components/bookmarks/browser/bookmark_utils.h" -#include "components/bookmarks/common/bookmark_pref_names.h" -#include "components/prefs/pref_service.h" -#include "ui/base/models/tree_node_iterator.h" - -using bookmarks::BookmarkNode; -using bookmarks::BookmarkModel; - -namespace { - -class ScopedPauseObserver { - public: - explicit ScopedPauseObserver(brave_sync::BookmarkChangeProcessor* processor) : - processor_(processor) { - DCHECK_NE(processor_, nullptr); - processor_->Stop(); - } - ~ScopedPauseObserver() { - processor_->Start(); - } - - private: - brave_sync::BookmarkChangeProcessor* processor_; // Not owned -}; - -const char kDeletedBookmarksTitle[] = "Deleted Bookmarks"; -const char kPendingBookmarksTitle[] = "Pending Bookmarks"; - -std::unique_ptr - MakePermanentNode(const std::string& title, int64_t* next_node_id) { - using brave_sync::BraveBookmarkPermanentNode; - auto node = std::make_unique(*next_node_id); - (*next_node_id)++; - node->set_type(bookmarks::BookmarkNode::FOLDER); - node->set_visible(false); - node->SetTitle(base::UTF8ToUTF16(title)); - - return node; -} - -} // namespace - -namespace brave_sync { - -bool IsSyncManagedNodeDeleted(const bookmarks::BookmarkPermanentNode* node) { - return node->GetTitledUrlNodeTitle() == - base::UTF8ToUTF16(kDeletedBookmarksTitle); -} - -bool IsSyncManagedNodePending(const bookmarks::BookmarkPermanentNode* node) { - return node->GetTitledUrlNodeTitle() == - base::UTF8ToUTF16(kPendingBookmarksTitle); -} - -bool IsSyncManagedNode(const bookmarks::BookmarkPermanentNode* node) { - return IsSyncManagedNodeDeleted(node) || IsSyncManagedNodePending(node); -} - -bookmarks::BookmarkPermanentNodeList -LoadExtraNodes(bookmarks::LoadExtraCallback callback, - int64_t* next_node_id) { - // TODO(bridiver) - deleted node should not be visible - bookmarks::BookmarkPermanentNodeList extra_nodes; - if (callback) - extra_nodes = std::move(callback).Run(next_node_id); - - auto deleted_node = MakePermanentNode(kDeletedBookmarksTitle, next_node_id); - extra_nodes.push_back(std::move(deleted_node)); - - auto pending_node = MakePermanentNode(kPendingBookmarksTitle, next_node_id); - extra_nodes.push_back(std::move(pending_node)); - - return extra_nodes; -} - -namespace { - -void GetOrder(const bookmarks::BookmarkNode* parent, - int index, - std::string* prev_order, - std::string* next_order, - std::string* parent_order) { - DCHECK_GE(index, 0); - auto* prev_node = index == 0 ? - nullptr : - parent->GetChild(index - 1); - auto* next_node = index == parent->child_count() - 1 ? - nullptr : - parent->GetChild(index + 1); - - if (prev_node) - prev_node->GetMetaInfo("order", prev_order); - - if (next_node) - next_node->GetMetaInfo("order", next_order); - - parent->GetMetaInfo("order", parent_order); -} - -void GetPrevObjectId(const bookmarks::BookmarkNode* parent, - int index, - std::string* prev_object_id) { - DCHECK_GE(index, 0); - auto* prev_node = index == 0 ? - nullptr : - parent->GetChild(index - 1); - - if (prev_node) - prev_node->GetMetaInfo("object_id", prev_object_id); -} - -const bookmarks::BookmarkNode* FindByObjectId(bookmarks::BookmarkModel* model, - const std::string& object_id) { - ui::TreeNodeIterator - iterator(model->root_node()); - while (iterator.has_next()) { - const bookmarks::BookmarkNode* node = iterator.Next(); - std::string node_object_id; - node->GetMetaInfo("object_id", &node_object_id); - - if (!node_object_id.empty() && object_id == node_object_id) - return node; - } - return nullptr; -} - -uint64_t GetIndexByOrder(const bookmarks::BookmarkNode* root_node, - const std::string& record_order) { - int index = 0; - while (index < root_node->child_count()) { - const bookmarks::BookmarkNode* node = root_node->GetChild(index); - std::string node_order; - node->GetMetaInfo("order", &node_order); - - if (!node_order.empty() && - brave_sync::CompareOrder(record_order, node_order)) - return index; - - ++index; - } - return index; -} - -uint64_t GetIndex(const bookmarks::BookmarkNode* root_node, - const jslib::Bookmark& record) { - return GetIndexByOrder(root_node, record.order); -} - -// this should only be called for resolved records we get from the server -void UpdateNode(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node, - const jslib::SyncRecord* record, - const bookmarks::BookmarkNode* pending_node_root = nullptr) { - auto bookmark = record->GetBookmark(); - if (bookmark.isFolder) { - // SetDateFolderModified - } else { - model->SetURL(node, GURL(bookmark.site.location)); - // TODO(alexeyb): apply these: - // sync_bookmark.site.customTitle - // sync_bookmark.site.lastAccessedTime - // sync_bookmark.site.favicon - } - - const auto& title = !bookmark.site.title.empty() ? - bookmark.site.title : bookmark.site.customTitle; - model->SetTitle(node, - base::UTF8ToUTF16(title)); - model->SetDateAdded(node, bookmark.site.creationTime); - model->SetNodeMetaInfo(node, "object_id", record->objectId); - model->SetNodeMetaInfo(node, "order", bookmark.order); - - if (pending_node_root && node->parent() == pending_node_root) { - model->SetNodeMetaInfo(node, "parent_object_id", - bookmark.parentFolderObjectId); - } -} - -const bookmarks::BookmarkNode* FindParent(bookmarks::BookmarkModel* model, - const jslib::Bookmark& bookmark, - bookmarks::BookmarkNode* - pending_node_root) { - auto* parent_node = FindByObjectId(model, bookmark.parentFolderObjectId); - - if (!parent_node) { - if (!bookmark.parentFolderObjectId.empty()) { - return pending_node_root; - } - if ( - // this flag is a bit odd, but if the node doesn't have a parent and - // hideInToolbar is false, then this bookmark should go in the - // toolbar root. We don't care about this flag for records with - // a parent id because they will be inserted into the correct - // parent folder - !bookmark.hideInToolbar || - // mobile generated bookmarks go also in bookmark bar - (!bookmark.order.empty() && bookmark.order.at(0) == '2')) { - parent_node = model->bookmark_bar_node(); - } else { - parent_node = model->other_node(); - } - } - - return parent_node; -} - -} // namespace - -// static -BookmarkChangeProcessor* BookmarkChangeProcessor::Create( - Profile* profile, - BraveSyncClient* sync_client, - prefs::Prefs* sync_prefs) { - return new BookmarkChangeProcessor(profile, sync_client, sync_prefs); -} - -BookmarkChangeProcessor::BookmarkChangeProcessor( - Profile* profile, - BraveSyncClient* sync_client, - prefs::Prefs* sync_prefs) - : sync_client_(sync_client), - sync_prefs_(sync_prefs), - profile_(profile), - bookmark_model_(BookmarkModelFactory::GetForBrowserContext( - Profile::FromBrowserContext(profile))), - deleted_node_root_(nullptr), - pending_node_root_(nullptr) { - DCHECK(sync_client_); - DCHECK(sync_prefs); - DCHECK(bookmark_model_); -} - -BookmarkChangeProcessor::~BookmarkChangeProcessor() { - Stop(); -} - -void BookmarkChangeProcessor::Start() { - bookmark_model_->AddObserver(this); -} - -void BookmarkChangeProcessor::Stop() { - if (bookmark_model_) - bookmark_model_->RemoveObserver(this); -} - -void BookmarkChangeProcessor::BookmarkModelLoaded(BookmarkModel* model, - bool ids_reassigned) { - // This may be invoked after bookmarks import - VLOG(1) << __func__; -} - -void BookmarkChangeProcessor::BookmarkModelBeingDeleted( - bookmarks::BookmarkModel* model) { - NOTREACHED(); - bookmark_model_ = nullptr; -} - -void BookmarkChangeProcessor::BookmarkNodeAdded(BookmarkModel* model, - const BookmarkNode* parent, - int index) { -} - -void BookmarkChangeProcessor::OnWillRemoveBookmarks(BookmarkModel* model, - const BookmarkNode* parent, - int old_index, - const BookmarkNode* node) { -} - - -void BookmarkChangeProcessor::CloneBookmarkNodeForDeleteImpl( - const bookmarks::BookmarkNodeData::Element& element, - bookmarks::BookmarkNode* parent, - int index) { - auto cloned_node = - std::make_unique(element.id(), element.url); - if (!element.is_url) { - cloned_node->set_type(bookmarks::BookmarkNode::FOLDER); - for (int i = 0; i < static_cast(element.children.size()); ++i) - CloneBookmarkNodeForDeleteImpl(element.children[i], cloned_node.get(), i); - } else { - // default type is URL and we will hit - // [url_index.cc(122)] "Check failed: i != nodes_ordered_by_url_set_.end()." - // However, clone nodes should be dummy nodes which only need - // object_id meta info. - cloned_node->set_type(bookmarks::BookmarkNode::OTHER_NODE); - } - cloned_node->SetTitle(element.title); - - // clear sync timestsamp so this sends in unsynced records - bookmarks::BookmarkNode::MetaInfoMap meta_info_map = element.meta_info_map; - meta_info_map.erase("sync_timestamp"); - cloned_node->SetMetaInfoMap(meta_info_map); - - auto* cloned_node_ptr = cloned_node.get(); - parent->Add(std::move(cloned_node), index); - // we call `Changed` here because we don't want to update the order - BookmarkNodeChanged(bookmark_model_, cloned_node_ptr); -} - -void BookmarkChangeProcessor::CloneBookmarkNodeForDelete( - const std::vector& elements, - bookmarks::BookmarkNode* parent, - int index) { - for (size_t i = 0; i < elements.size(); ++i) { - CloneBookmarkNodeForDeleteImpl( - elements[i], parent, index + static_cast(i)); - } -} - -void BookmarkChangeProcessor::BookmarkNodeRemoved( - BookmarkModel* model, - const BookmarkNode* parent, - int old_index, - const BookmarkNode* node, - const std::set& no_longer_bookmarked) { - // TODO(bridiver) - should this be in OnWillRemoveBookmarks? - // copy into the deleted node tree without firing any events - - // The node which has not yet been sent, should not be cloned into removed. - std::string node_object_id; - node->GetMetaInfo("object_id", &node_object_id); - if (node_object_id.empty()) { - return; - } - - auto* deleted_node = GetDeletedNodeRoot(); - CHECK(deleted_node); - bookmarks::BookmarkNodeData data(node); - CloneBookmarkNodeForDelete( - data.elements, deleted_node, deleted_node->child_count()); -} - -void BookmarkChangeProcessor::BookmarkAllUserNodesRemoved( - BookmarkModel* model, - const std::set& removed_urls) { - // this only happens on profile deletion and we don't want - // to wipe out the remote store when that happens -} - -void BookmarkChangeProcessor::BookmarkNodeChanged(BookmarkModel* model, - const BookmarkNode* node) { - // clearing the sync_timestamp will put the record back in the `Unsynced` list - model->DeleteNodeMetaInfo(node, "sync_timestamp"); - // also clear the last send time because this is a new change - model->DeleteNodeMetaInfo(node, "last_send_time"); - - model->SetNodeMetaInfo(node, - "last_updated_time", - std::to_string(base::Time::Now().ToJsTime())); -} - -void BookmarkChangeProcessor::BookmarkMetaInfoChanged( - BookmarkModel* model, const BookmarkNode* node) { - // Ignore metadata changes. - // These are: - // Brave managed: "object_id", "order", "sync_timestamp", - // "last_send_time", "last_updated_time" - // Chromium managed: kBookmarkLastVisitDateOnMobileKey, - // kBookmarkLastVisitDateOnDesktopKey, kBookmarkDismissedFromNTP, - // submitted by private JS API - // Not interested in any of these. -} - -void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model, - const BookmarkNode* old_parent, int old_index, - const BookmarkNode* new_parent, int new_index) { - auto* node = new_parent->GetChild(new_index); - model->DeleteNodeMetaInfo(node, "order"); - BookmarkNodeChanged(model, node); - // TODO(darkdh): handle old_parent == new_parent to avoid duplicate order - // clearing. Also https://github.com/brave/sync/issues/231 blocks update to - // another devices - for (int i = old_index; i < old_parent->child_count(); ++i) { - auto* shifted_node = old_parent->GetChild(i); - model->DeleteNodeMetaInfo(shifted_node, "order"); - BookmarkNodeChanged(model, shifted_node); - } - for (int i = new_index; i < new_parent->child_count(); ++i) { - auto* shifted_node = new_parent->GetChild(i); - model->DeleteNodeMetaInfo(shifted_node, "order"); - BookmarkNodeChanged(model, shifted_node); - } -} - -void BookmarkChangeProcessor::BookmarkNodeFaviconChanged( - BookmarkModel* model, - const BookmarkNode* node) { - // TODO(darkdh): This will be triggered right after apply sync CREATE records - // So the node applied from sync record will be put into unsync list - // BookmarkNodeChanged(model, node); -} - -void BookmarkChangeProcessor::BookmarkNodeChildrenReordered( - BookmarkModel* model, const BookmarkNode* node) { - // this should be safe to ignore as it's only called for managed bookmarks -} - -void BookmarkChangeProcessor::Reset(bool clear_meta_info) { - ui::TreeNodeIterator - iterator(bookmark_model_->root_node()); - bookmark_model_->BeginExtensiveChanges(); - - if (clear_meta_info) { - while (iterator.has_next()) { - const bookmarks::BookmarkNode* node = iterator.Next(); - bookmark_model_->DeleteNodeMetaInfo(node, "object_id"); - bookmark_model_->DeleteNodeMetaInfo(node, "order"); - bookmark_model_->DeleteNodeMetaInfo(node, "sync_timestamp"); - bookmark_model_->DeleteNodeMetaInfo(node, "last_send_time"); - bookmark_model_->DeleteNodeMetaInfo(node, "last_updated_time"); - } - } - - auto* deleted_node = GetDeletedNodeRoot(); - CHECK(deleted_node); - deleted_node->DeleteAll(); - auto* pending_node = GetPendingNodeRoot(); - CHECK(pending_node); - pending_node->DeleteAll(); - bookmark_model_->EndExtensiveChanges(); -} - -void BookmarkChangeProcessor::DeleteSelfAndChildren( - const bookmarks::BookmarkNode* node) { - DCHECK(node->is_folder()); - for (int i = 0; i < node->child_count(); ++i) { - if (node->GetChild(i)->is_folder()) { - DeleteSelfAndChildren(node->GetChild(i)); - } else { - bookmark_model_->Remove(node->GetChild(i)); - } - } - bookmark_model_->Remove(node); -} - -void ValidateFolderOrders(const bookmarks::BookmarkNode* folder_node) { - DCHECK(folder_node); - - // Validate direct children order - std::string left_order; - std::string right_order; - for (auto i = 0; i < folder_node->child_count(); ++i) { - const auto* node = folder_node->GetChild(i); - std::string order; - node->GetMetaInfo("order", &order); - if (order.empty()) { - continue; - } - - if (left_order.empty()) { - left_order = order; - continue; - } - - if (right_order.empty()) { - right_order = order; - } else { - left_order = right_order; - right_order = order; - } - - DCHECK(!left_order.empty()); - DCHECK(!right_order.empty()); - - bool compare_result = CompareOrder(left_order, right_order); - if (!compare_result) { - DLOG(ERROR) << "ValidateFolderOrders failed"; - DLOG(ERROR) << "folder_node=" << folder_node->GetTitle(); - DLOG(ERROR) << "folder_node->child_count()=" << - folder_node->child_count(); - DLOG(ERROR) << "i=" << i; - DLOG(ERROR) << "left_order=" << left_order; - DLOG(ERROR) << "right_order=" << right_order; - DLOG(ERROR) << "Unexpected situation of invalid order"; - return; - } - } -} - -void BookmarkChangeProcessor::ApplyChangesFromSyncModel( - const RecordsList &records) { - ScopedPauseObserver pause(this); - bookmark_model_->BeginExtensiveChanges(); - for (const auto& sync_record : records) { - DCHECK(sync_record->has_bookmark()); - DCHECK(!sync_record->objectId.empty()); - - auto* node = FindByObjectId(bookmark_model_, sync_record->objectId); - auto bookmark_record = sync_record->GetBookmark(); - - if (node && sync_record->action == jslib::SyncRecord::Action::A_UPDATE) { - int64_t old_parent_local_id = node->parent()->id(); - const bookmarks::BookmarkNode* old_parent_node = - bookmarks::GetBookmarkNodeByID(bookmark_model_, old_parent_local_id); - - std::string old_parent_object_id; - if (old_parent_node) { - old_parent_node->GetMetaInfo("object_id", &old_parent_object_id); - } - - const bookmarks::BookmarkNode* new_parent_node = nullptr; - if (bookmark_record.parentFolderObjectId != old_parent_object_id) { - new_parent_node = FindParent(bookmark_model_, bookmark_record, - GetPendingNodeRoot()); - } - - if (new_parent_node) { - DCHECK(!bookmark_record.order.empty()); - int64_t index = GetIndex(new_parent_node, bookmark_record); - bookmark_model_->Move(node, new_parent_node, index); - } else if (!bookmark_record.order.empty()) { - std::string order; - node->GetMetaInfo("order", &order); - DCHECK(!order.empty()); - if (bookmark_record.order != order) { - int64_t index = GetIndex(node->parent(), bookmark_record); - bookmark_model_->Move(node, node->parent(), index); - } - } - UpdateNode(bookmark_model_, node, sync_record.get()); - } else if (node && - sync_record->action == jslib::SyncRecord::Action::A_DELETE) { - if (node->parent() == GetDeletedNodeRoot()) { - // this is a deleted node so remove without firing events - int index = GetDeletedNodeRoot()->GetIndexOf(node); - GetDeletedNodeRoot()->Remove(index); - } else { - // normal remove - if (node->is_folder()) { - DeleteSelfAndChildren(node); - } else { - bookmark_model_->Remove(node); - } - } - } else if (sync_record->action == jslib::SyncRecord::Action::A_CREATE) { - bool folder_was_created = false; - const bookmarks::BookmarkNode* parent_node = nullptr; - if (!node) { - // TODO(bridiver) make sure there isn't an existing record for objectId - parent_node = - FindParent(bookmark_model_, bookmark_record, GetPendingNodeRoot()); - - const BookmarkNode* bookmark_bar = bookmark_model_->bookmark_bar_node(); - bool bookmark_bar_was_empty = bookmark_bar->children().empty(); - - if (bookmark_record.isFolder) { - node = bookmark_model_->AddFolder( - parent_node, - GetIndex(parent_node, bookmark_record), - base::UTF8ToUTF16(bookmark_record.site.title)); - folder_was_created = true; - } else { - node = bookmark_model_->AddURL(parent_node, - GetIndex(parent_node, bookmark_record), - base::UTF8ToUTF16(bookmark_record.site.title), - GURL(bookmark_record.site.location)); - } - if (bookmark_bar_was_empty) - profile_->GetPrefs()->SetBoolean(bookmarks::prefs::kShowBookmarkBar, - true); - } - UpdateNode(bookmark_model_, node, sync_record.get(), - GetPendingNodeRoot()); - -#ifndef NDEBUG - if (parent_node) { - ValidateFolderOrders(parent_node); - } -#endif - - if (folder_was_created) { - CompletePendingNodesMove(node, sync_record->objectId); - } - } - } - bookmark_model_->EndExtensiveChanges(); -} - -void BookmarkChangeProcessor::CompletePendingNodesMove( - const bookmarks::BookmarkNode* created_folder_node, - const std::string& created_folder_object_id) { - DCHECK(GetPendingNodeRoot()); - - // node, node_order - using MoveInfo = std::tuple; - std::vector move_infos; - - bookmarks::BookmarkNode* pending_node_root = GetPendingNodeRoot(); - for (int i = 0; i < pending_node_root->child_count(); ++i) { - bookmarks::BookmarkNode* node = pending_node_root->GetChild(i); - - std::string parent_object_id; - node->GetMetaInfo("parent_object_id", &parent_object_id); - if (parent_object_id.empty()) { - // The node has been attached to folder which is still in Pending nodes - continue; - } - - if (created_folder_object_id != parent_object_id) { - // Node is still pending, because waits for another parent - continue; - } - - std::string order; - node->GetMetaInfo("order", &order); - - DCHECK(!order.empty()); - move_infos.push_back(std::make_tuple(node, order)); - } - - for (auto& move_info : move_infos) { - auto* node = std::get<0>(move_info); - const auto& order = std::get<1>(move_info); - int64_t index = GetIndexByOrder(created_folder_node, order); - - bookmark_model_->Move(node, created_folder_node, index); - // Now we dont need "parent_object_id" metainfo on node, because node - // is attached to proper parent. Note that parent can still be a child - // of "Pending Bookmarks" note. - node->DeleteMetaInfo("parent_object_id"); -#ifndef NDEBUG - ValidateFolderOrders(created_folder_node); -#endif - } -} - -int BookmarkChangeProcessor::GetPermanentNodeIndex( - const bookmarks::BookmarkNode* node) const { - DCHECK(node->is_permanent_node()); - if (node == bookmark_model_->bookmark_bar_node()) { - return 1; - } else if (node == bookmark_model_->other_node()) { - return 2; - } else if (node == bookmark_model_->mobile_node()) { - LOG(WARNING) << "[BraveSync] " << __func__ << " unexpected mobile_node"; - return 3; - } else if (node == - const_cast(this)->GetDeletedNodeRoot()) { - // Brave defined pseudo node for storing deleted bookmark until get - // acknowledge about record present in sync cloud - return 4; - } else { - NOTREACHED(); - return -1; - } -} - -std::unique_ptr -BookmarkChangeProcessor::BookmarkNodeToSyncBookmark( - const bookmarks::BookmarkNode* node) { - if (node->is_permanent_node() || !node->parent()) - return std::unique_ptr(); - - auto record = std::make_unique(); - record->deviceId = sync_prefs_->GetThisDeviceId(); - record->objectData = jslib_const::SyncObjectData_BOOKMARK; - - auto bookmark = std::make_unique(); - bookmark->site.location = node->url().spec(); - bookmark->site.title = base::UTF16ToUTF8(node->GetTitledUrlNodeTitle()); - bookmark->site.customTitle = base::UTF16ToUTF8(node->GetTitle()); - // bookmark->site.lastAccessedTime - ignored - bookmark->site.creationTime = node->date_added(); - bookmark->site.favicon = node->icon_url() ? node->icon_url()->spec() : ""; - // Url may have type OTHER_NODE if it is in Deleted Bookmarks - bookmark->isFolder = (node->type() != bookmarks::BookmarkNode::URL && - node->type() != bookmarks::BookmarkNode::OTHER_NODE); - bookmark->hideInToolbar = - !node->HasAncestor(bookmark_model_->bookmark_bar_node()); - - std::string object_id; - node->GetMetaInfo("object_id", &object_id); - record->objectId = object_id; - - std::string parent_object_id; - node->parent()->GetMetaInfo("object_id", &parent_object_id); - bookmark->parentFolderObjectId = parent_object_id; - - std::string order; - node->GetMetaInfo("order", &order); - bookmark->order = order; - - int index = node->parent()->GetIndexOf(node); - std::string prev_object_id; - GetPrevObjectId(node->parent(), index, &prev_object_id); - bookmark->prevObjectId = prev_object_id; - - std::string prev_order, next_order, parent_order; - GetOrder(node->parent(), index, &prev_order, &next_order, &parent_order); - if (parent_order.empty() && node->parent()->is_permanent_node()) { - int permanent_parent_index = GetPermanentNodeIndex(node->parent()); - parent_order = - sync_prefs_->GetBookmarksBaseOrder() + - std::to_string(permanent_parent_index); - } - bookmark->prevOrder = prev_order; - bookmark->nextOrder = next_order; - bookmark->parentOrder = parent_order; - - auto* deleted_node = GetDeletedNodeRoot(); - CHECK(deleted_node); - std::string sync_timestamp; - node->GetMetaInfo("sync_timestamp", &sync_timestamp); - - if (!sync_timestamp.empty()) { - record->syncTimestamp = base::Time::FromJsTime(std::stod(sync_timestamp)); - } else { - record->syncTimestamp = base::Time::Now(); - } - - // Situation below means the node was created and then deleted before send - // Should be ignored - if (record->objectId.empty() && node->HasAncestor(deleted_node)) { - return nullptr; - } - - if (record->objectId.empty()) { - record->objectId = tools::GenerateObjectId(); - record->action = jslib::SyncRecord::Action::A_CREATE; - bookmark_model_->SetNodeMetaInfo(node, "object_id", record->objectId); - } else if (node->HasAncestor(deleted_node)) { - record->action = jslib::SyncRecord::Action::A_DELETE; - } else { - record->action = jslib::SyncRecord::Action::A_UPDATE; - DCHECK(!record->objectId.empty()); - } - - record->SetBookmark(std::move(bookmark)); - - return record; -} - -bool IsUnsynced(const bookmarks::BookmarkNode* node) { - std::string sync_timestamp; - node->GetMetaInfo("sync_timestamp", &sync_timestamp); - - if (sync_timestamp.empty()) - return true; - - std::string last_updated_time; - node->GetMetaInfo("last_updated_time", &last_updated_time); - - return !last_updated_time.empty() && - base::Time::FromJsTime(std::stod(last_updated_time)) > - base::Time::FromJsTime(std::stod(sync_timestamp)); -} - -void BookmarkChangeProcessor::GetAllSyncData( - const std::vector>& records, - SyncRecordAndExistingList* records_and_existing_objects) { - for (const auto& record : records) { - auto resolved_record = std::make_unique(); - resolved_record->first = jslib::SyncRecord::Clone(*record); - auto* node = FindByObjectId(bookmark_model_, record->objectId); - if (node) { - resolved_record->second = BookmarkNodeToSyncBookmark(node); - // Update "sync_timestamp" - bookmark_model_->SetNodeMetaInfo(node, - "sync_timestamp", - std::to_string(record->syncTimestamp.ToJsTime())); - } - - records_and_existing_objects->push_back(std::move(resolved_record)); - } -} - -bookmarks::BookmarkNode* BookmarkChangeProcessor::GetDeletedNodeRoot() { - if (!deleted_node_root_) { - ui::TreeNodeIterator - iterator(bookmark_model_->root_node()); - while (iterator.has_next()) { - const bookmarks::BookmarkNode* node = iterator.Next(); - if (node->is_permanent_node() && - IsSyncManagedNodeDeleted( - static_cast(node))) { - deleted_node_root_ = const_cast(node); - return deleted_node_root_; - } - } - } - DCHECK(deleted_node_root_); - return deleted_node_root_; -} - -bookmarks::BookmarkNode* BookmarkChangeProcessor::GetPendingNodeRoot() { - if (!pending_node_root_) { - ui::TreeNodeIterator - iterator(bookmark_model_->root_node()); - while (iterator.has_next()) { - const bookmarks::BookmarkNode* node = iterator.Next(); - if (node->is_permanent_node() && - IsSyncManagedNodePending( - static_cast(node))) { - pending_node_root_ = const_cast(node); - return pending_node_root_; - } - } - } - DCHECK(pending_node_root_); - return pending_node_root_; -} - -int BookmarkChangeProcessor::FindMigrateSubOrderLength( - const std::string& order) { - // Old order subject to be migrated is ... - // Return value is the substring length before the 3rd point - - if (order.length() < 6) { - DCHECK(false) << "The minimal length of order required is 6, like '1.0.1.'"; - return -1; - } - - // 1st segment is guaranteed to be "1" or "2" - size_t pos2 = order.find('.', 2); - if (std::string::npos == pos2) { - DCHECK(false) << "Should find 2nd '.' in order"; - return -1; - } - - size_t pos3 = order.find('.', pos2 + 1); - if (std::string::npos == pos3) { - DCHECK(false) << "Should find 3rd '.' in order"; - return -1; - } - - std::string third_segment(order.begin() + pos2 + 1, order.begin() + pos3); - if (third_segment != "0") { - // No need to migrate - return -1; - } - - if (pos3 == order.length() - 1) { - DLOG(WARNING) << "Should have at least one digit after 3rd '.'"; - return -1; - } - - return pos3; -} - -void BookmarkChangeProcessor::MigrateOrdersForPermanentNode( - bookmarks::BookmarkNode* permanent_node) { - - // Before After - // bookmarks_bar child "order":"1.0.0.1" "order":"1.0.1.1" - // other_bookmarks child "order":"1.0.0.1" "order":"1.0.2.1" - - // The old order part to be migrated is ... - // The substring before the 3rd point - // Third segment should be "0" only for migration - - int permanent_node_index = GetPermanentNodeIndex(permanent_node); - std::string perm_new_order = sync_prefs_->GetBookmarksBaseOrder() + - std::to_string(permanent_node_index); - - ui::TreeNodeIterator - iterator(permanent_node); - while (iterator.has_next()) { - bookmarks::BookmarkNode* node = iterator.Next(); - - std::string old_node_order; - if (node->GetMetaInfo("order", &old_node_order) - && !old_node_order.empty()) { - int old_suborder_length = FindMigrateSubOrderLength(old_node_order); - if (old_suborder_length == -1) { - continue; - } - - std::string new_node_order = perm_new_order + - old_node_order.substr(old_suborder_length); - - node->SetMetaInfo("order", new_node_order); - BookmarkNodeChanged(bookmark_model_, node); - } - } -} - -void BookmarkChangeProcessor::MigrateOrders() { - if (sync_prefs_->GetMigratedBookmarksVersion() >= 1) { - return; - } - for (const auto* node : { bookmark_model_->bookmark_bar_node(), - bookmark_model_->other_node() }) { - MigrateOrdersForPermanentNode(const_cast(node)); - } - - sync_prefs_->SetMigratedBookmarksVersion(1); -} - -void BookmarkChangeProcessor::SendUnsynced( - base::TimeDelta unsynced_send_interval) { - MigrateOrders(); - - std::vector> records; - - auto* deleted_node = GetDeletedNodeRoot(); - CHECK(deleted_node); - std::vector root_nodes = { - bookmark_model_->other_node(), - bookmark_model_->bookmark_bar_node(), - deleted_node - }; - - for (const auto* root_node : root_nodes) { - ui::TreeNodeIterator - iterator(root_node); - while (iterator.has_next()) { - const bookmarks::BookmarkNode* node = iterator.Next(); - - // only send unsynced records - if (!IsUnsynced(node)) - continue; - - std::string last_send_time; - node->GetMetaInfo("last_send_time", &last_send_time); - if (!last_send_time.empty() && - // don't send more often than unsynced_send_interval_ - (base::Time::Now() - - base::Time::FromJsTime(std::stod(last_send_time))) < - unsynced_send_interval) - continue; - - bookmark_model_->SetNodeMetaInfo(node, - "last_send_time", std::to_string(base::Time::Now().ToJsTime())); - - auto record = BookmarkNodeToSyncBookmark(node); - if (record) - records.push_back(std::move(record)); - - if (records.size() == 1000) { - sync_client_->SendSyncRecords( - jslib_const::SyncRecordType_BOOKMARKS, records); - records.clear(); - } - } - } - if (!records.empty()) { - sync_client_->SendSyncRecords( - jslib_const::SyncRecordType_BOOKMARKS, records); - records.clear(); - } - sync_client_->ClearOrderMap(); -} - -void BookmarkChangeProcessor::InitialSync() {} - -void BookmarkChangeProcessor::ApplyOrder(const std::string& object_id, - const std::string& order) { - ScopedPauseObserver pause(this); - auto* node = FindByObjectId(bookmark_model_, object_id); - if (node) { - bookmark_model_->SetNodeMetaInfo(node, "order", order); - } -} - -} // namespace brave_sync diff --git a/components/brave_sync/client/bookmark_change_processor.h b/components/brave_sync/client/bookmark_change_processor.h deleted file mode 100644 index b80e5ba03358..000000000000 --- a/components/brave_sync/client/bookmark_change_processor.h +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright 2018 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/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BOOKMARK_CHANGE_PROCESSOR_H_ -#define BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BOOKMARK_CHANGE_PROCESSOR_H_ - -#include -#include -#include -#include - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/time/time.h" -#include "brave/components/brave_sync/brave_sync_prefs.h" -#include "brave/components/brave_sync/client/brave_sync_client.h" -#include "brave/components/brave_sync/model/change_processor.h" -#include "components/bookmarks/browser/bookmark_model_observer.h" -#include "components/bookmarks/browser/bookmark_node.h" -#include "components/bookmarks/browser/bookmark_node_data.h" - -FORWARD_DECLARE_TEST(BraveBookmarkChangeProcessorTest, IgnoreRapidCreateDelete); -FORWARD_DECLARE_TEST(BraveBookmarkChangeProcessorTest, - MigrateOrdersForPermanentNodes); - -class BraveBookmarkChangeProcessorTest; - -namespace brave_sync { - -class BookmarkChangeProcessor : public ChangeProcessor, - bookmarks::BookmarkModelObserver { - public: - static BookmarkChangeProcessor* Create( - Profile* profile, - BraveSyncClient* sync_client, - prefs::Prefs* sync_prefs); - ~BookmarkChangeProcessor() override; - - // ChangeProcessor implementation - void Start() override; - void Stop() override; - void Reset(bool clear_meta_info) override; - void ApplyChangesFromSyncModel(const RecordsList &records) override; - void GetAllSyncData( - const std::vector>& records, - SyncRecordAndExistingList* records_and_existing_objects) override; - void SendUnsynced(base::TimeDelta unsynced_send_interval) override; - void InitialSync() override; - - void ApplyOrder(const std::string& object_id, const std::string& order); - - private: - friend class ::BraveBookmarkChangeProcessorTest; - FRIEND_TEST_ALL_PREFIXES(::BraveBookmarkChangeProcessorTest, - IgnoreRapidCreateDelete); - FRIEND_TEST_ALL_PREFIXES(::BraveBookmarkChangeProcessorTest, - MigrateOrdersForPermanentNodes); - - BookmarkChangeProcessor(Profile* profile, - BraveSyncClient* sync_client, - prefs::Prefs* sync_prefs); - - // bookmarks::BookmarkModelObserver: - void BookmarkModelLoaded(bookmarks::BookmarkModel* model, - bool ids_reassigned) override; - void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; - void BookmarkNodeMoved(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* old_parent, - int old_index, - const bookmarks::BookmarkNode* new_parent, - int new_index) override; - void BookmarkNodeAdded(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* parent, - int index) override; - void OnWillRemoveBookmarks(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* parent, - int old_index, - const bookmarks::BookmarkNode* node) override; - void BookmarkNodeRemoved(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* parent, - int old_index, - const bookmarks::BookmarkNode* node, - const std::set& no_longer_bookmarked) override; - void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel* model, - const std::set& removed_urls) override; - void BookmarkNodeChanged(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node) override; - void BookmarkMetaInfoChanged(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node) override; - void BookmarkNodeFaviconChanged(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node) override; - void BookmarkNodeChildrenReordered( - bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node) override; - - std::unique_ptr BookmarkNodeToSyncBookmark( - const bookmarks::BookmarkNode* node); - bookmarks::BookmarkNode* GetDeletedNodeRoot(); - bookmarks::BookmarkNode* GetPendingNodeRoot(); - void CloneBookmarkNodeForDeleteImpl( - const bookmarks::BookmarkNodeData::Element& element, - bookmarks::BookmarkNode* parent, - int index); - void CloneBookmarkNodeForDelete( - const std::vector& elements, - bookmarks::BookmarkNode* parent, - int index); - // BookmarkModel::Remove will remove parent but put its children under - // "Other Bookmarks" so we need to explicitly delete children - void DeleteSelfAndChildren(const bookmarks::BookmarkNode* node); - - void CompletePendingNodesMove( - const bookmarks::BookmarkNode* created_folder_node, - const std::string& created_folder_object_id); - - void MigrateOrders(); - void MigrateOrdersForPermanentNode(bookmarks::BookmarkNode* perm_node); - int GetPermanentNodeIndex(const bookmarks::BookmarkNode* node) const; - static int FindMigrateSubOrderLength(const std::string& order); - - BraveSyncClient* sync_client_; // not owned - prefs::Prefs* sync_prefs_; // not owned - Profile* profile_; // not owned - bookmarks::BookmarkModel* bookmark_model_; // not owned - - bookmarks::BookmarkNode* deleted_node_root_; - bookmarks::BookmarkNode* pending_node_root_; - - DISALLOW_COPY_AND_ASSIGN(BookmarkChangeProcessor); -}; - -} // namespace brave_sync - -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BOOKMARK_CHANGE_PROCESSOR_H_ diff --git a/components/brave_sync/client/bookmark_change_processor_unittest.cc b/components/brave_sync/client/bookmark_change_processor_unittest.cc deleted file mode 100644 index 0f4dc9fa0e69..000000000000 --- a/components/brave_sync/client/bookmark_change_processor_unittest.cc +++ /dev/null @@ -1,1468 +0,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 -#include -#include -#include - -#include "base/files/scoped_temp_dir.h" -#include "base/strings/utf_string_conversions.h" -#include "brave/components/brave_sync/client/bookmark_change_processor.h" -#include "brave/components/brave_sync/client/brave_sync_client_impl.h" -#include "brave/components/brave_sync/client/client_ext_impl_data.h" -#include "brave/components/brave_sync/brave_sync_service_impl.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" -#include "brave/components/brave_sync/brave_sync_service_observer.h" -#include "brave/components/brave_sync/jslib_const.h" -#include "brave/components/brave_sync/jslib_messages.h" -#include "brave/components/brave_sync/test_util.h" -#include "chrome/browser/bookmarks/bookmark_model_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "components/bookmarks/browser/bookmark_model.h" -#include "components/bookmarks/browser/bookmark_utils.h" -#include "components/bookmarks/common/bookmark_pref_names.h" -#include "components/bookmarks/test/test_bookmark_client.h" -#include "components/prefs/pref_service.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -// npm run test -- brave_unit_tests --filter=BraveBookmarkChangeProcessorTest.* - -// BookmarkChangeProcessor::methods -// Name | Covered -//------------------------------------- -// Create | + in SetUp -// Start | + -// Stop | + -// Reset | + -// ApplyChangesFromSyncModel | + -// GetAllSyncData | + -// SendUnsynced | + -// InitialSync | N/A -// ApplyOrder | + - -// bookmarks::BookmarkModelObserver overrides: -// Name | Covered -// BookmarkModelLoaded | N/A -// BookmarkModelBeingDeleted | N/A -// BookmarkNodeMoved | + -// BookmarkNodeAdded | N/A -// OnWillRemoveBookmarks | N/A -// BookmarkNodeRemoved | + -// BookmarkAllUserNodesRemoved | N/A -// BookmarkNodeChanged | + -// BookmarkMetaInfoChanged | + -// BookmarkNodeFaviconChanged | + - -using testing::_; -using testing::AtLeast; - -using bookmarks::BookmarkClient; -using bookmarks::BookmarkModel; -using bookmarks::BookmarkNode; - -using brave_sync::jslib::SyncRecord; -using brave_sync::MockBraveSyncClient; -using brave_sync::RecordsList; -using brave_sync::SimpleBookmarkSyncRecord; -using brave_sync::SimpleFolderSyncRecord; - -MATCHER_P2(ContainsRecord, action, location, - "contains sync record with params") { - for (const auto& record : arg) { - if (record->has_bookmark()) { - const auto& bookmark = record->GetBookmark(); - if (record->action == action && - bookmark.site.location == location) { - return true; - } - } - } - return false; -} - -MATCHER_P(RecordsNumber, expected_number, - "contains specified sync record number") { - return static_cast(arg.size()) == static_cast(expected_number); -} - -MATCHER_P(AllRecordsHaveAction, expected_action, - "all records have expected action") { - if (arg.empty()) { - return false; - } - - for (const auto& record : arg) { - if (record->action != expected_action) { - return false; - } - } - return true; -} - -class BraveBookmarkChangeProcessorTest : public testing::Test { - public: - BraveBookmarkChangeProcessorTest() {} - ~BraveBookmarkChangeProcessorTest() override {} - - protected: - void SetUp() override { - EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); - - profile_ = brave_sync::CreateBraveSyncProfile(temp_dir_.GetPath()); - EXPECT_TRUE(profile_.get() != NULL); - - sync_client_.reset(new MockBraveSyncClient()); - - BookmarkModelFactory::GetInstance()->SetTestingFactory( - profile_.get(), - base::BindRepeating(&brave_sync::BuildFakeBookmarkModelForTests)); - - model_ = BookmarkModelFactory::GetForBrowserContext( - Profile::FromBrowserContext(profile_.get())); - - sync_prefs_.reset(new brave_sync::prefs::Prefs(profile_->GetPrefs())); - - change_processor_.reset(brave_sync::BookmarkChangeProcessor::Create( - profile_.get(), - sync_client(), - sync_prefs_.get() )); - - EXPECT_NE(sync_client(), nullptr); - EXPECT_NE(bookmark_client(), nullptr); - EXPECT_NE(model(), nullptr); - EXPECT_NE(change_processor(), nullptr); - } - - void TearDown() override { - change_processor()->Stop(); - change_processor_.reset(); - profile_.reset(); - } - - MockBraveSyncClient* sync_client() { return sync_client_.get(); } - BookmarkClient* bookmark_client() { return model_->client(); } - BookmarkModel* model() { return model_; } - brave_sync::prefs::Prefs* sync_prefs() { return sync_prefs_.get(); } - brave_sync::BookmarkChangeProcessor* change_processor() { - return change_processor_.get(); - } - const bookmarks::BookmarkPermanentNode* GetDeletedNodeRoot() { - return static_cast( - change_processor_->GetDeletedNodeRoot()); - } - const bookmarks::BookmarkPermanentNode* GetPendingNodeRoot() { - return static_cast( - change_processor_->GetPendingNodeRoot()); - } - - void BookmarkAddedImpl(); - void BookmarkCreatedFromSyncImpl(); - bool HasAnySyncMetaInfo(const BookmarkNode* node); - void AddSimpleHierarchy( - const BookmarkNode** folder1, const BookmarkNode** node_a, - const BookmarkNode** node_b, const BookmarkNode** node_c); - - private: - // Need this as a very first member to run tests in UI thread - // When this is set, class should not install any other MessageLoops, like - // base::test::ScopedTaskEnvironment - content::TestBrowserThreadBundle thread_bundle_; - - std::unique_ptr sync_client_; - BookmarkModel* model_; // Not owns - std::unique_ptr change_processor_; - std::unique_ptr profile_; - std::unique_ptr sync_prefs_; - base::ScopedTempDir temp_dir_; -}; - -TEST_F(BraveBookmarkChangeProcessorTest, StartObserver) { - // The mark of observer processed: metainfo "last_updated_time" is set - const auto* node_a = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("A.com - title"), - GURL("https://a.com/")); - model()->SetTitle(node_a, base::ASCIIToUTF16("A.com - title - upated")); - std::string last_updated_time_a; - node_a->GetMetaInfo("last_updated_time", &last_updated_time_a); - EXPECT_TRUE(last_updated_time_a.empty()); - - change_processor()->Start(); - - const auto* node_b = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("B.com - title"), - GURL("https://b.com/")); - model()->SetTitle(node_b, base::ASCIIToUTF16("B.com - title - upated")); - std::string last_updated_time_b; - node_b->GetMetaInfo("last_updated_time", &last_updated_time_b); - EXPECT_TRUE(!last_updated_time_b.empty()); -} - -TEST_F(BraveBookmarkChangeProcessorTest, StopObserver) { - // The mark of observer processed: metainfo "last_updated_time" is set - change_processor()->Start(); - const auto* node_a = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("A.com - title"), - GURL("https://a.com/")); - model()->SetTitle(node_a, base::ASCIIToUTF16("A.com - title - upated")); - std::string last_updated_time_a; - node_a->GetMetaInfo("last_updated_time", &last_updated_time_a); - EXPECT_TRUE(!last_updated_time_a.empty()); - - change_processor()->Stop(); - - const auto* node_b = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("B.com - title"), - GURL("https://b.com/")); - model()->SetTitle(node_b, base::ASCIIToUTF16("B.com - title - upated")); - std::string last_updated_time_b; - node_b->GetMetaInfo("last_updated_time", &last_updated_time_b); - EXPECT_TRUE(last_updated_time_b.empty()); -} - -bool BraveBookmarkChangeProcessorTest::HasAnySyncMetaInfo( - const BookmarkNode* node) { - DCHECK(node); - const std::vector keys = {"object_id", "order", "sync_timestamp", - "last_send_time", "last_updated_time", "parent_object_id"}; - for (const auto& key : keys) { - std::string value; - if (node->GetMetaInfo(key, &value) && !value.empty()) { - return true; - } - } - return false; -} - -void BraveBookmarkChangeProcessorTest::AddSimpleHierarchy( - const BookmarkNode** folder1, const BookmarkNode** node_a, - const BookmarkNode** node_b, const BookmarkNode** node_c) { - *folder1 = model()->AddFolder(model()->other_node(), 0, - base::ASCIIToUTF16("Folder1")); - - *node_a = model()->AddURL(*folder1, 0, - base::ASCIIToUTF16("A.com - title"), - GURL("https://a.com/")); - - *node_b = model()->AddURL(*folder1, 1, - base::ASCIIToUTF16("B.com - title"), - GURL("https://b.com/")); - - *node_c = model()->AddURL(*folder1, 2, - base::ASCIIToUTF16("C.com - title"), - GURL("https://c.com/")); -} - -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(); - - 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); - EXPECT_CALL(*sync_client(), ClearOrderMap()).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()->children().empty()); - EXPECT_FALSE(GetPendingNodeRoot()->children().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()->children().empty()); - EXPECT_TRUE(GetPendingNodeRoot()->children().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); - EXPECT_CALL(*sync_client(), ClearOrderMap()).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()->children().empty()); - EXPECT_FALSE(GetPendingNodeRoot()->children().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()->children().empty()); - EXPECT_TRUE(GetPendingNodeRoot()->children().empty()); -} - - -TEST_F(BraveBookmarkChangeProcessorTest, DISABLED_InitialSync) { - // BookmarkChangeProcessor::InitialSync does not do anything now - // All work for obtaining order is done in background.js -} - -void BraveBookmarkChangeProcessorTest::BookmarkAddedImpl() { - change_processor()->Start(); - - bookmarks::AddIfNotBookmarked(model(), - GURL("https://a.com/"), - base::ASCIIToUTF16("A.com - title")); - - using brave_sync::jslib::SyncRecord; - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", - ContainsRecord(SyncRecord::Action::A_CREATE, "https://a.com/"))).Times(1); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkAdded) { - BookmarkAddedImpl(); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkDeleted) { - // Add bookmark first - BookmarkAddedImpl(); - using brave_sync::jslib::SyncRecord; - - // And just now can actually test delete - std::vector nodes; - bookmarks::GetMostRecentlyAddedEntries(model(), 1, &nodes); - ASSERT_EQ(nodes.size(), 1u); - ASSERT_NE(nodes.at(0), nullptr); - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", - ContainsRecord(SyncRecord::Action::A_DELETE, "https://a.com/"))).Times(1); - model()->Remove(nodes.at(0)); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); - EXPECT_FALSE(GetDeletedNodeRoot()->IsVisible()); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkModified) { - // Add bookmark first - BookmarkAddedImpl(); - using brave_sync::jslib::SyncRecord; - - // And just now can actually test modify - std::vector nodes; - bookmarks::GetMostRecentlyAddedEntries(model(), 1, &nodes); - ASSERT_EQ(nodes.size(), 1u); - ASSERT_NE(nodes.at(0), nullptr); - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", - ContainsRecord(SyncRecord::Action::A_UPDATE, - "https://a-m.com/"))).Times(1); - model()->SetURL(nodes.at(0), GURL("https://a-m.com/")); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkMovedInFolder) { - 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); - - int intex_a = folder1->GetIndexOf(node_a); - EXPECT_EQ(intex_a, 0); - int intex_b = folder1->GetIndexOf(node_b); - EXPECT_EQ(intex_b, 1); - int intex_c = folder1->GetIndexOf(node_c); - EXPECT_EQ(intex_c, 2); - - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(1); - EXPECT_CALL(*sync_client(), ClearOrderMap()).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()->Move(node_a, folder1, 2); - - intex_a = folder1->GetIndexOf(node_a); - EXPECT_EQ(intex_a, 1); - intex_b = folder1->GetIndexOf(node_b); - EXPECT_EQ(intex_b, 0); - intex_c = folder1->GetIndexOf(node_c); - EXPECT_EQ(intex_c, 2); - - - // Sould see at least one syncRecord Modified - using brave_sync::jslib::SyncRecord; - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", - AllRecordsHaveAction(SyncRecord::Action::A_UPDATE))).Times(1); - // BookmarkNodeMoved does not reset "last_send_time" so SendUnsynced - // ignores order change untill unsynced_send_interval passes, - // so here below unsynced_send_interval is 0 - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(0)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, DISABLED_MoveNodesBetweenDirs) { - // 1. Create these: - // Other - // Folder1 - // a.com - // Folder2 - // b.com - // 2. Move b.com => Folder1 - - change_processor()->Start(); - - const auto* folder1 = model()->AddFolder(model()->other_node(), 0, - base::ASCIIToUTF16("Folder1")); - - [[maybe_unused]] const auto* node_a = model()->AddURL(folder1, 0, - base::ASCIIToUTF16("A.com - title"), - GURL("https://a.com/")); - - const auto* folder2 = model()->AddFolder(model()->other_node(), 1, - base::ASCIIToUTF16("Folder2")); - [[maybe_unused]] const auto* node_b = model()->AddURL(folder2, 0, - base::ASCIIToUTF16("B.com - title"), - GURL("https://b.com/")); - - // Send all created objects - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", - RecordsNumber(4))).Times(1); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, DeleteFolderWithNodes) { - // 1. Create these: - // Other - // Folder1 - // a.com - // b.com - // c.com - // 2. Delete Folder1 - - 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", - RecordsNumber(4))).Times(1); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); - - model()->Remove(folder1); - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(1); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); -} - -// Another type of tests with `change_processor()->ApplyChangesFromSyncModel` -// Without any mocks -// May ignore order, because it will be moved into background.js - -void BraveBookmarkChangeProcessorTest::BookmarkCreatedFromSyncImpl() { - change_processor()->Start(); - - RecordsList records; - const char* record_a_object_id = - "121, 194, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - record_a_object_id, - "https://a.com/", - "A.com - title", - "1.1.1.1", "")); - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://b.com/", - "B.com - title", - "1.1.1.2", "")); - - change_processor()->ApplyChangesFromSyncModel(records); - - // Expecting we can find the bookmarks in a model - std::vector nodes_a; - model()->GetNodesByURL(GURL("https://a.com/"), &nodes_a); - ASSERT_EQ(nodes_a.size(), 1u); - const auto* node_a = nodes_a.at(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); - - std::vector nodes_b; - model()->GetNodesByURL(GURL("https://b.com/"), &nodes_b); - ASSERT_EQ(nodes_b.size(), 1u); - const auto* node_b = nodes_b.at(0); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); - - EXPECT_EQ(node_a->parent(), node_b->parent()); - - int index_a = node_a->parent()->GetIndexOf(node_a); - EXPECT_NE(index_a, -1); - - int index_b = node_b->parent()->GetIndexOf(node_b); - EXPECT_NE(index_b, -1); - - EXPECT_LT(index_a, index_b); - - EXPECT_TRUE(profile_->GetPrefs()->GetBoolean( - bookmarks::prefs::kShowBookmarkBar)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkCreatedFromSync) { - BookmarkCreatedFromSyncImpl(); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkRemovedFromSync) { - BookmarkCreatedFromSyncImpl(); - - RecordsList records; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_DELETE, - "121, 194, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130", - "https://a.com/", - "A.com - title", - "1.1.1.1", "")); - - change_processor()->ApplyChangesFromSyncModel(records); - std::vector nodes_a; - model()->GetNodesByURL(GURL("https://a.com/"), &nodes_a); - ASSERT_EQ(nodes_a.size(), 0u); - - std::vector nodes_b; - model()->GetNodesByURL(GURL("https://b.com/"), &nodes_b); - ASSERT_EQ(nodes_b.size(), 1u); - const auto* node_b = nodes_b.at(0); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); -} - -TEST_F(BraveBookmarkChangeProcessorTest, NestedFoldersCreatedFromSync) { - // Create these: - // Other - // Folder1 - // Folder2 - // Folder3 - // a.com - // b.com - // Then verify in a model - - change_processor()->Start(); - - RecordsList records; - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder1", - "1.1.1.1", - "", true, "")); - - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder2", - "1.1.1.1.1", - records.at(0)->objectId, - true, "")); - - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder3", - "1.1.1.1.1.1", - records.at(1)->objectId, - true, "")); - - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://a.com/", - "A.com - title", - "1.1.1.1.1.1.1", - records.at(2)->objectId)); - - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://b.com/", - "B.com - title", - "1.1.1.1.1.1.2", - records.at(2)->objectId)); - - change_processor()->ApplyChangesFromSyncModel(records); - - // Verify the model - ASSERT_EQ(model()->other_node()->child_count(), 1); - const auto* folder1 = model()->other_node()->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder1->GetTitle()), "Folder1"); - - ASSERT_EQ(folder1->child_count(), 1); - const auto* folder2 = folder1->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder2->GetTitle()), "Folder2"); - - ASSERT_EQ(folder2->child_count(), 1); - const auto* folder3 = folder2->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder3->GetTitle()), "Folder3"); - - ASSERT_EQ(folder3->child_count(), 2); - const auto* node_a = folder3->GetChild(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); - const auto* node_b = folder3->GetChild(1); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); -} - -TEST_F(BraveBookmarkChangeProcessorTest, ChildrenOfPermanentNodesFromSync) { - // Record with 1.x.y order, with hideInToolbar=false and empty - // parent_object_id should go to toolbar node - // Record with 2.x.y order, without parent_object_id should go to mobile_node - // Record with 1.x.y order, with hideInToolbar=true and empty - // parent_object_id should go to other_node - - change_processor()->Start(); - - RecordsList records; - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder1", - "1.1.1", - "", false, "")); - - ASSERT_EQ(model()->bookmark_bar_node()->child_count(), 0); - change_processor()->ApplyChangesFromSyncModel(records); - ASSERT_EQ(model()->bookmark_bar_node()->child_count(), 1); - const auto* folder1 = model()->bookmark_bar_node()->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder1->GetTitle()), "Folder1"); - - records.clear(); - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder2", - "2.1.1", - "", false, "")); - ASSERT_EQ(model()->mobile_node()->child_count(), 0); - change_processor()->ApplyChangesFromSyncModel(records); - ASSERT_EQ(model()->mobile_node()->child_count(), 0); - ASSERT_EQ(model()->bookmark_bar_node()->child_count(), 2); - const auto* folder2 = model()->bookmark_bar_node()->GetChild(1); - EXPECT_EQ(base::UTF16ToUTF8(folder2->GetTitle()), "Folder2"); - - records.clear(); - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder3", - "1.1.1", - "", true, "")); - ASSERT_EQ(model()->other_node()->child_count(), 0); - change_processor()->ApplyChangesFromSyncModel(records); - ASSERT_EQ(model()->other_node()->child_count(), 1); - const auto* folder3 = model()->other_node()->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder3->GetTitle()), "Folder3"); -} - -TEST_F(BraveBookmarkChangeProcessorTest, Utf8FromSync) { - // Send Greek text - const wchar_t* const title_wide = - L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9" - L"\x03bf\x03c2\x0020\x0399\x03c3\x03c4\x03cc\x03c2"; - auto title_wide_len = std::wcslen(title_wide); - - std::string title_utf8; - ASSERT_TRUE(base::WideToUTF8(title_wide, title_wide_len, &title_utf8)); - - base::string16 title_utf16; - ASSERT_TRUE(base::WideToUTF16(title_wide, title_wide_len, &title_utf16)); - - change_processor()->Start(); - - RecordsList records; - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - title_utf8, - "1.1.1", - "", false, "")); - - ASSERT_EQ(model()->bookmark_bar_node()->child_count(), 0); - change_processor()->ApplyChangesFromSyncModel(records); - const auto* folder1 = model()->bookmark_bar_node()->GetChild(0); - EXPECT_EQ(folder1->GetTitle(), title_utf16); -} - -TEST_F(BraveBookmarkChangeProcessorTest, ChangeOrderUnderSameParentFromSync) { - BookmarkCreatedFromSyncImpl(); - - RecordsList records; - const char* record_a_object_id = - "121, 194, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_UPDATE, - record_a_object_id, - "https://a.com/", - "A.com - title", - "1.1.1.2", "")); - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_UPDATE, - "", - "https://b.com/", - "B.com - title", - "1.1.1.1", "")); - - change_processor()->ApplyChangesFromSyncModel(records); - - // Expecting we can find the bookmarks in a model - std::vector nodes_a; - model()->GetNodesByURL(GURL("https://a.com/"), &nodes_a); - ASSERT_EQ(nodes_a.size(), 1u); - const auto* node_a = nodes_a.at(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); - - std::vector nodes_b; - model()->GetNodesByURL(GURL("https://b.com/"), &nodes_b); - ASSERT_EQ(nodes_b.size(), 1u); - const auto* node_b = nodes_b.at(0); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); - - EXPECT_EQ(node_a->parent(), node_b->parent()); - - int index_a = node_a->parent()->GetIndexOf(node_a); - EXPECT_NE(index_a, -1); - - int index_b = node_b->parent()->GetIndexOf(node_b); - EXPECT_NE(index_b, -1); - - EXPECT_LT(index_b, index_a); -} - -::testing::AssertionResult AssertSyncRecordsBookmarkEqual( - const char* left_expr, - const char* right_expr, - SyncRecord* left, - SyncRecord* right) { - DCHECK(left); - DCHECK(right); - - DCHECK(left->has_bookmark()); - DCHECK(right->has_bookmark()); - - #define FAIL_IF_FIELD_NOT_EQUAL(FIELD_NAME) \ - if (left->FIELD_NAME != right->FIELD_NAME) { \ - return ::testing::AssertionFailure() << left_expr << " and " << right_expr \ - << " are not equal by " << #FIELD_NAME << " field (" \ - << left->FIELD_NAME << " vs " << right->FIELD_NAME << ")"; \ - } - - // Ignore action and device_id - FAIL_IF_FIELD_NOT_EQUAL(objectId); - FAIL_IF_FIELD_NOT_EQUAL(GetBookmark().site.location); - FAIL_IF_FIELD_NOT_EQUAL(GetBookmark().site.title); - FAIL_IF_FIELD_NOT_EQUAL(GetBookmark().isFolder); - FAIL_IF_FIELD_NOT_EQUAL(GetBookmark().parentFolderObjectId); - FAIL_IF_FIELD_NOT_EQUAL(GetBookmark().order); - #undef FAIL_IF_FIELD_NOT_EQUAL - - return ::testing::AssertionSuccess(); -} - -TEST_F(BraveBookmarkChangeProcessorTest, GetAllSyncData) { - // This is a resolve operation in terms of sync js lib - // 1) ApplyChangesFromSyncModel - // 2) GetAllSyncData() => (must resolve) => SyncRecordAndExistingList - // 3) Verify all is good - - change_processor()->Start(); - - RecordsList records; - const char* record_a_object_id = - "111, 111, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - record_a_object_id, - "https://a.com/", - "A.com - title", - "1.1.1.1", "")); - const char* record_b_object_id = - "222, 222, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - record_b_object_id, - "https://b.com/", - "B.com - title", - "1.1.1.2", "")); - const char* record_c_object_id = - "33, 33, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - record_c_object_id, - "https://c.com/", - "C.com - title", - "1.1.1.3", "")); - - change_processor()->ApplyChangesFromSyncModel(records); - - RecordsList records_to_resolve; - - records_to_resolve.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_UPDATE, - record_b_object_id, - "https://b.com/", - "B.com - title - modified", - "1.1.1.2", "")); - - records_to_resolve.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_DELETE, - record_c_object_id, - "https://c.com/", - "C.com - title", - "1.1.1.3", "")); - - const char* record_d_object_id = - "44, 44, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records_to_resolve.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - record_d_object_id, - "https://d.com/", - "D.com - title", - "1.1.1.4", "")); - - brave_sync::SyncRecordAndExistingList records_and_existing_objects; - change_processor()->GetAllSyncData(records_to_resolve, - &records_and_existing_objects); - ASSERT_EQ(records_and_existing_objects.size(), 3u); - - const auto& pair_at_0 = records_and_existing_objects.at(0); - - EXPECT_PRED_FORMAT2(AssertSyncRecordsBookmarkEqual, - records_to_resolve.at(0).get(), pair_at_0->first.get()); - EXPECT_PRED_FORMAT2(AssertSyncRecordsBookmarkEqual, - records.at(1).get(), pair_at_0->second.get()); - - const auto& pair_at_1 = records_and_existing_objects.at(1); - EXPECT_PRED_FORMAT2(AssertSyncRecordsBookmarkEqual, - records_to_resolve.at(1).get(), pair_at_1->first.get()); - EXPECT_PRED_FORMAT2(AssertSyncRecordsBookmarkEqual, - records.at(2).get(), pair_at_1->second.get()); - - const auto& pair_at_2 = records_and_existing_objects.at(2); - EXPECT_PRED_FORMAT2(AssertSyncRecordsBookmarkEqual, - records_to_resolve.at(2).get(), pair_at_2->first.get()); - EXPECT_EQ(pair_at_2->second.get(), nullptr); -} - -TEST_F(BraveBookmarkChangeProcessorTest, TitleCustomTitle) { - // Should be able to create folder when title = "" and customTitle != "" - // Create these: - // Other - // Folder1 (use title) - // Folder2 (use customTitle) - // Then verify in a model - - change_processor()->Start(); - - RecordsList records; - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder1", - "1.1.1.1", - "", true, "")); - - records.push_back(SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "1.1.1.1.1", - records.at(0)->objectId, - true, - "Folder2")); - - change_processor()->ApplyChangesFromSyncModel(records); - - // Verify the model - ASSERT_EQ(model()->other_node()->child_count(), 1); - const auto* folder1 = model()->other_node()->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder1->GetTitle()), "Folder1"); - - ASSERT_EQ(folder1->child_count(), 1); - const auto* folder2 = folder1->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder2->GetTitle()), "Folder2"); -} - -TEST_F(BraveBookmarkChangeProcessorTest, BookmarkFromMobileGoesToToolbar) { - change_processor()->Start(); - auto a_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://a.com/", - "A.com - title", - "2.1.1", - ""); - RecordsList records; - records.push_back(std::move(a_record)); - change_processor()->ApplyChangesFromSyncModel(records); - // Verify the model, now we should find the folder and the nodes - EXPECT_EQ(model()->other_node()->child_count(), 0); - EXPECT_EQ(model()->mobile_node()->child_count(), 0); - ASSERT_EQ(model()->bookmark_bar_node()->child_count(), 1); - - const auto* node_a = model()->bookmark_bar_node()->GetChild(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); -} - -TEST_F(BraveBookmarkChangeProcessorTest, ItemAheadOfFolder) { - // Create these: - // Other - // Folder1 - // a.com - // b.com - // With a broken sequence - // Then verify in a model - - change_processor()->Start(); - - auto folder1_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder1", - "1.1.1.1.1.1", - "", true, ""); - - auto a_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://a.com/", - "A.com - title", - "1.1.1.1.1.1.1", - folder1_record->objectId); - - auto b_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://b.com/", - "B.com - title", - "1.1.1.1.1.1.2", - folder1_record->objectId); - - RecordsList records; - records.push_back(std::move(a_record)); - records.push_back(std::move(b_record)); - - change_processor()->ApplyChangesFromSyncModel(records); - - // Verify the model, for now we should not find anything - EXPECT_EQ(model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://a.com/")), - nullptr); - EXPECT_EQ(model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://b.com/")), - nullptr); - - RecordsList records2; - records2.push_back(std::move(folder1_record)); - change_processor()->ApplyChangesFromSyncModel(records2); - - // Verify the model, now we should find the folder and the nodes - ASSERT_EQ(model()->other_node()->child_count(), 1); - const auto* folder1 = model()->other_node()->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder1->GetTitle()), "Folder1"); - - ASSERT_EQ(folder1->child_count(), 2); - const auto* node_a = folder1->GetChild(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); - const auto* node_b = folder1->GetChild(1); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); - EXPECT_FALSE(GetPendingNodeRoot()->IsVisible()); -} - -TEST_F(BraveBookmarkChangeProcessorTest, ItemAheadOfFolderAgressive) { - // Send these: - // Other - // Folder1 - // Folder2 - // Folder3 - // a.com - // b.com - // In a backwards order: - // b.com, a.com, - // Folder2, - // Folder3, - // Folder1 - // Then verify in a model - - change_processor()->Start(); - - auto folder1_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder1", - "1.1.1.1", - "", true, ""); - - auto folder2_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder2", - "1.1.1.1.1", - folder1_record->objectId, - true, ""); - - auto folder3_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder3", - "1.1.1.1.1.1", - folder2_record->objectId, - true, ""); - - auto a_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://a.com/", - "A.com - title", - "1.1.1.1.1.1.1", - folder3_record->objectId); - - auto b_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://b.com/", - "B.com - title", - "1.1.1.1.1.1.2", - folder3_record->objectId); - - // Send in a backwards order - { - RecordsList records1; - records1.push_back(std::move(b_record)); - records1.push_back(std::move(a_record)); - change_processor()->ApplyChangesFromSyncModel(records1); - - // Verify the model, for now we should not find anything - EXPECT_EQ( - model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://a.com/")), - nullptr); - EXPECT_EQ( - model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://b.com/")), - nullptr); - } - - { - RecordsList records2; - records2.push_back(std::move(folder2_record)); - change_processor()->ApplyChangesFromSyncModel(records2); - EXPECT_EQ( - model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://a.com/")), - nullptr); - EXPECT_EQ( - model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://b.com/")), - nullptr); - } - - { - RecordsList records3; - records3.push_back(std::move(folder3_record)); - change_processor()->ApplyChangesFromSyncModel(records3); - EXPECT_EQ( - model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://a.com/")), - nullptr); - EXPECT_EQ( - model()->GetMostRecentlyAddedUserNodeForURL(GURL("https://b.com/")), - nullptr); - // TODO(alexeyb): Verify there are some records attached to - // "Pending Bookmarks" node - } - - { - RecordsList records4; - records4.push_back(std::move(folder1_record)); - change_processor()->ApplyChangesFromSyncModel(records4); - } - - // Verify now all is as expected - ASSERT_EQ(model()->other_node()->child_count(), 1); - const auto* folder1 = model()->other_node()->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder1->GetTitle()), "Folder1"); - - ASSERT_EQ(folder1->child_count(), 1); - const auto* folder2 = folder1->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder2->GetTitle()), "Folder2"); - - ASSERT_EQ(folder2->child_count(), 1); - const auto* folder3 = folder2->GetChild(0); - EXPECT_EQ(base::UTF16ToUTF8(folder3->GetTitle()), "Folder3"); - - ASSERT_EQ(folder3->child_count(), 2); - const auto* node_a = folder3->GetChild(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); - const auto* node_b = folder3->GetChild(1); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); - EXPECT_FALSE(GetPendingNodeRoot()->IsVisible()); -} - -TEST_F(BraveBookmarkChangeProcessorTest, - ItemAheadOfFolderRequireStrictSorting) { - // Send these: - // Other - // +--0-1.com 1.1.1.1 - // +--Folder1 1.1.1.2 - // | +--1-1.com 1.1.1.2.1 - // | +--Folder2 1.1.1.2.2 - // | | +--2-1.com 1.1.1.2.2.1 - // | | +--Folder3 1.1.1.2.2.2 - // | | | +--a.com 1.1.1.2.2.2.1 - // | | | +--b.com 1.1.1.2.2.2.2 - // | | +--2-2.com 1.1.1.2.2.3 - // | | +--2-3.com 1.1.1.2.2.4 - // | +--1-2.com 1.1.1.2.3 - // +--0-2.com 1.1.1.3 - // - // In an order: - // Folder2, 2-1.com, Folder3, a.com, b.com - // 2-3.com, 2-2.com, 1-2.com - // Folder1, 0-1.com, 0-2.com, 1-1.com - // Then verify in a model - - change_processor()->Start(); - - auto folder1_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder1", - "1.1.1.2", - "", true, ""); - - auto folder2_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder2", - "1.1.1.2.2", - folder1_record->objectId, - true, ""); - - auto folder3_record = SimpleFolderSyncRecord( - SyncRecord::Action::A_CREATE, - "Folder3", - "1.1.1.2.2.2", - folder2_record->objectId, - true, ""); - - auto _0_1_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://0-1.com/", - "0-1.com - title", - "1.1.1.1", - ""); - auto _0_2_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://0-2.com/", - "0-2.com - title", - "1.1.1.3", - ""); - - auto _1_1_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://1-1.com/", - "1-1.com - title", - "1.1.1.2.1", - folder1_record->objectId); - auto _1_2_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://1-2.com/", - "1-2.com - title", - "1.1.1.2.3", - folder1_record->objectId); - - auto _2_1_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://2-1.com/", - "2-1.com - title", - "1.1.1.2.2.1", - folder2_record->objectId); - auto _2_2_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://2-2.com/", - "2-2.com - title", - "1.1.1.2.2.3", - folder2_record->objectId); - auto _2_3_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://2-3.com/", - "2-3.com - title", - "1.1.1.2.2.4", - folder2_record->objectId); - - auto a_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://a.com/", - "A.com - title", - "1.1.1.1.1.1.1", - folder3_record->objectId); - - auto b_record = SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - "", - "https://b.com/", - "B.com - title", - "1.1.1.1.1.1.2", - folder3_record->objectId); - - // Send in an order - { - RecordsList records1; - records1.push_back(std::move(folder2_record)); - records1.push_back(std::move(_2_1_record)); - records1.push_back(std::move(folder3_record)); - records1.push_back(std::move(a_record)); - records1.push_back(std::move(b_record)); - change_processor()->ApplyChangesFromSyncModel(records1); - } - - { - RecordsList records2; - // 2-3 before 2-2 is important - records2.push_back(std::move(_2_3_record)); - records2.push_back(std::move(_2_2_record)); - records2.push_back(std::move(_1_2_record)); - change_processor()->ApplyChangesFromSyncModel(records2); - } - - { - RecordsList records3; - records3.push_back(std::move(folder1_record)); - records3.push_back(std::move(_0_1_record)); - records3.push_back(std::move(_0_2_record)); - records3.push_back(std::move(_1_1_record)); - - change_processor()->ApplyChangesFromSyncModel(records3); - } - - // Verify now all is as expected - ASSERT_EQ(model()->other_node()->child_count(), 3); - const auto* node_0_1 = model()->other_node()->GetChild(0); - EXPECT_EQ(node_0_1->url().spec(), "https://0-1.com/"); - const auto* folder1 = model()->other_node()->GetChild(1); - EXPECT_EQ(base::UTF16ToUTF8(folder1->GetTitle()), "Folder1"); - const auto* node_0_2 = model()->other_node()->GetChild(2); - EXPECT_EQ(node_0_2->url().spec(), "https://0-2.com/"); - - ASSERT_EQ(folder1->child_count(), 3); - const auto* node_1_1 = folder1->GetChild(0); - EXPECT_EQ(node_1_1->url().spec(), "https://1-1.com/"); - const auto* folder2 = folder1->GetChild(1); - EXPECT_EQ(base::UTF16ToUTF8(folder2->GetTitle()), "Folder2"); - const auto* node_1_2 = folder1->GetChild(2); - EXPECT_EQ(node_1_2->url().spec(), "https://1-2.com/"); - - ASSERT_EQ(folder2->child_count(), 4); - const auto* node_2_1 = folder2->GetChild(0); - EXPECT_EQ(node_2_1->url().spec(), "https://2-1.com/"); - const auto* folder3 = folder2->GetChild(1); - EXPECT_EQ(base::UTF16ToUTF8(folder3->GetTitle()), "Folder3"); - // Below fails if GetIndex uses tree iteartor - const auto* node_2_2 = folder2->GetChild(2); - EXPECT_EQ(node_2_2->url().spec(), "https://2-2.com/"); - - ASSERT_EQ(folder3->child_count(), 2); - const auto* node_a = folder3->GetChild(0); - EXPECT_EQ(node_a->url().spec(), "https://a.com/"); - const auto* node_b = folder3->GetChild(1); - EXPECT_EQ(node_b->url().spec(), "https://b.com/"); - EXPECT_FALSE(GetPendingNodeRoot()->IsVisible()); -} - -TEST_F(BraveBookmarkChangeProcessorTest, IgnoreRapidCreateDelete) { - change_processor()->Start(); - - const auto* node_a = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("A.com - title"), - GURL("https://a.com/")); - model()->Remove(node_a); - - EXPECT_EQ(change_processor()->GetDeletedNodeRoot()->child_count(), 0); - - // Expect there will be no calls, because no any records to send - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(0); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, IgnoreMetadataSet) { - change_processor()->Start(); - - const auto* node_a = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("A.com - title"), - GURL("https://a.com/")); - - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); - - model()->SetNodeMetaInfo(node_a, "last_visited", "2019"); - // Not interested in metadata changes, expecting no calls - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(0); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); -} - -TEST_F(BraveBookmarkChangeProcessorTest, MigrateOrdersForPermanentNodes) { - EXPECT_EQ(change_processor()->GetPermanentNodeIndex( - model()->bookmark_bar_node()), 1); - EXPECT_EQ(change_processor()->GetPermanentNodeIndex( - model()->other_node()), 2); - - using brave_sync::BookmarkChangeProcessor; - EXPECT_EQ(BookmarkChangeProcessor::FindMigrateSubOrderLength("1.0.0.1"), 5); - EXPECT_EQ(BookmarkChangeProcessor::FindMigrateSubOrderLength("1.12.0.1"), 6); - EXPECT_EQ(BookmarkChangeProcessor::FindMigrateSubOrderLength("1.12.1.1"), -1); - EXPECT_EQ(BookmarkChangeProcessor::FindMigrateSubOrderLength("1.0.10."), -1); - EXPECT_EQ(BookmarkChangeProcessor::FindMigrateSubOrderLength("1.0.1."), -1); - - sync_prefs()->SetBookmarksBaseOrder("1.0."); - - change_processor()->Start(); - - EXPECT_EQ(sync_prefs()->GetMigratedBookmarksVersion(), 0); - - const auto* node_OB = model()->AddURL(model()->other_node(), 0, - base::ASCIIToUTF16("OB item - title"), - GURL("https://ob_item.com/")); - const_cast(node_OB)->SetMetaInfo( - "order", "1.0.0.1"); - - const auto* node_BB = model()->AddURL(model()->bookmark_bar_node(), 0, - base::ASCIIToUTF16("BB item - title"), - GURL("https://bb_item.com/")); - const_cast(node_BB)->SetMetaInfo( - "order", "1.0.0.1"); - - EXPECT_CALL(*sync_client(), SendSyncRecords("BOOKMARKS", _)).Times(1); - EXPECT_CALL(*sync_client(), ClearOrderMap()).Times(1); - change_processor()->SendUnsynced(base::TimeDelta::FromMinutes(10)); - - std::string OB_order, BB_order; - node_OB->GetMetaInfo("order", &OB_order); - node_BB->GetMetaInfo("order", &BB_order); - - EXPECT_EQ(BB_order, "1.0.1.1"); - EXPECT_EQ(OB_order, "1.0.2.1"); - - EXPECT_EQ(sync_prefs()->GetMigratedBookmarksVersion(), 1); -} - -TEST_F(BraveBookmarkChangeProcessorTest, ApplyOrder) { - BookmarkCreatedFromSyncImpl(); - const char* record_a_object_id = - "121, 194, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - const char* new_order = "1.1.1.3"; - change_processor()->ApplyOrder(record_a_object_id, new_order); - std::vector nodes_a; - model()->GetNodesByURL(GURL("https://a.com/"), &nodes_a); - ASSERT_EQ(nodes_a.size(), 1u); - const auto* node_a = nodes_a.at(0); - std::string order; - node_a->GetMetaInfo("order", &order); - EXPECT_EQ(order, new_order); -} - -namespace { - -const bookmarks::BookmarkNode* GetSingleNodeByUrl( - bookmarks::BookmarkModel* model, const std::string& url) { - std::vector nodes; - model->GetNodesByURL(GURL(url), &nodes); - size_t nodes_size = nodes.size(); - CHECK_EQ(nodes_size, 1u); - const bookmarks::BookmarkNode* node = nodes.at(0); - return node; -} - -} // namespace - -TEST_F(BraveBookmarkChangeProcessorTest, SyncTimestampMetaUpdateWay) { - // Should update "sync_timestamp": - // "get-existing-objects" => model => "resolve-sync-records" - // (GetAllSyncData) - // - // Should not update "sync_timestamp": - // "resolved-sync-records" => model - // (ApplyChangesFromSyncModel) - - change_processor()->Start(); - - RecordsList records; - const char* record_b_object_id = - "222, 222, 37, 61, 199, 11, 166, 234, " - "214, 197, 45, 215, 241, 206, 219, 130"; - records.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_CREATE, - record_b_object_id, - "https://b.com/", - "B.com - title", - "1.1.1.2", "")); - - change_processor()->ApplyChangesFromSyncModel(records); - - std::string node_b_sync_timestamp; - GetSingleNodeByUrl(model(), "https://b.com/")->GetMetaInfo( - "sync_timestamp", &node_b_sync_timestamp); - EXPECT_EQ(node_b_sync_timestamp, ""); - - RecordsList records_to_resolve; - records_to_resolve.push_back(SimpleBookmarkSyncRecord( - SyncRecord::Action::A_UPDATE, - record_b_object_id, - "https://b.com/", - "B.com - title - modified", - "1.1.1.2", "")); - auto timestamp_resolve = base::Time::Now(); - records_to_resolve.at(0)->syncTimestamp = timestamp_resolve; - - brave_sync::SyncRecordAndExistingList records_and_existing_objects; - change_processor()->GetAllSyncData(records_to_resolve, - &records_and_existing_objects); - GetSingleNodeByUrl(model(), "https://b.com/")->GetMetaInfo( - "sync_timestamp", &node_b_sync_timestamp); - - EXPECT_EQ(node_b_sync_timestamp, - std::to_string(timestamp_resolve.ToJsTime())); -} diff --git a/components/brave_sync/client/bookmark_node.cc b/components/brave_sync/client/bookmark_node.cc deleted file mode 100644 index 0118d7ffb92c..000000000000 --- a/components/brave_sync/client/bookmark_node.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include "brave/components/brave_sync/client/bookmark_node.h" - -namespace brave_sync { - -BraveBookmarkPermanentNode::BraveBookmarkPermanentNode(int64_t id) - : bookmarks::BookmarkPermanentNode(id) {} - -BraveBookmarkPermanentNode::~BraveBookmarkPermanentNode() = default; - -bool BraveBookmarkPermanentNode::IsVisible() const { - return visible_; -} - -} // namespace brave_sync diff --git a/components/brave_sync/client/bookmark_node.h b/components/brave_sync/client/bookmark_node.h deleted file mode 100644 index 5cd1c8d3b134..000000000000 --- a/components/brave_sync/client/bookmark_node.h +++ /dev/null @@ -1,31 +0,0 @@ -/* 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/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BOOKMARK_NODE_H_ -#define BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BOOKMARK_NODE_H_ - -#include "components/bookmarks/browser/bookmark_node.h" - -namespace brave_sync { - -// Sync Managed PerrmanentNode -class BraveBookmarkPermanentNode : public bookmarks::BookmarkPermanentNode { - public: - explicit BraveBookmarkPermanentNode(int64_t id); - ~BraveBookmarkPermanentNode() override; - - void set_visible(bool value) { visible_ = value; } - - // BookmarkNode overrides: - bool IsVisible() const override; - - private: - bool visible_ = false; - - DISALLOW_COPY_AND_ASSIGN(BraveBookmarkPermanentNode); -}; - -} // namespace brave_sync - -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BOOKMARK_NODE_H_ diff --git a/components/brave_sync/client/brave_sync_client.h b/components/brave_sync/client/brave_sync_client.h index 30ab3ac042c9..51d92092b9c5 100644 --- a/components/brave_sync/client/brave_sync_client.h +++ b/components/brave_sync/client/brave_sync_client.h @@ -51,8 +51,6 @@ class SyncMessageHandler { virtual void OnDeleteSyncSiteSettings() = 0; // SAVE_BOOKMARKS_BASE_ORDER virtual void OnSaveBookmarksBaseOrder(const std::string& order) = 0; - virtual void OnSaveBookmarkOrder(const std::string& object_id, - const std::string& order) = 0; virtual void OnSyncWordsPrepared(const std::string& words) = 0; }; @@ -88,8 +86,6 @@ class BraveSyncClient { virtual void OnExtensionInitialized() = 0; virtual void OnSyncEnabledChanged() = 0; - - virtual void ClearOrderMap() = 0; }; } // namespace brave_sync diff --git a/components/brave_sync/client/brave_sync_client_impl.cc b/components/brave_sync/client/brave_sync_client_impl.cc index 30d48f2f884b..1be22363b76f 100644 --- a/components/brave_sync/client/brave_sync_client_impl.cc +++ b/components/brave_sync/client/brave_sync_client_impl.cc @@ -34,9 +34,8 @@ void BraveSyncClientImpl::set_for_testing(BraveSyncClient* sync_client) { } // static -BraveSyncClient* BraveSyncClient::Create( - SyncMessageHandler* handler, - Profile* profile) { +BraveSyncClient* BraveSyncClient::Create(SyncMessageHandler* handler, + Profile* profile) { if (brave_sync_client_for_testing_) return brave_sync_client_for_testing_; @@ -69,7 +68,7 @@ void BraveSyncClientImpl::SendGotInitData(const Uint8Array& seed, const std::string& sync_words) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); extensions::api::brave_sync::Config config_extension; - ConvertConfig(config, config_extension); + ConvertConfig(config, &config_extension); brave_sync_event_router_->GotInitData(seed, device_id, config_extension, sync_words); } @@ -96,7 +95,7 @@ void BraveSyncClientImpl::SendResolveSyncRecords( records_and_existing_objects_ext; ConvertResolvedPairs(*records_and_existing_objects, - records_and_existing_objects_ext); + &records_and_existing_objects_ext); brave_sync_event_router_->ResolveSyncRecords(category_name, records_and_existing_objects_ext); @@ -106,7 +105,7 @@ void BraveSyncClientImpl::SendSyncRecords(const std::string &category_name, const RecordsList &records) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); std::vector records_ext; - ConvertSyncRecordsFromLibToExt(records, records_ext); + ConvertSyncRecordsFromLibToExt(records, &records_ext); brave_sync_event_router_->SendSyncRecords(category_name, records_ext); } @@ -151,8 +150,10 @@ void BraveSyncClientImpl::OnSyncEnabledChanged() { void BraveSyncClientImpl::OnExtensionReady( content::BrowserContext* browser_context, const extensions::Extension* extension) { - if (extension->id() == brave_sync_extension_id) + if (extension->id() == brave_sync_extension_id) { + DCHECK(handler_); handler_->BackgroundSyncStarted(true); + } } void BraveSyncClientImpl::OnExtensionLoaded( @@ -170,6 +171,7 @@ void BraveSyncClientImpl::OnExtensionUnloaded( extensions::UnloadedExtensionReason reason) { if (extension->id() == brave_sync_extension_id) { extension_loaded_ = false; + DCHECK(handler_); handler_->BackgroundSyncStopped(true); } } @@ -202,9 +204,4 @@ void BraveSyncClientImpl::OnExtensionSystemReady() { } } -void BraveSyncClientImpl::ClearOrderMap() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - brave_sync_event_router_->ClearOrderMap(); -} - } // namespace brave_sync diff --git a/components/brave_sync/client/brave_sync_client_impl.h b/components/brave_sync/client/brave_sync_client_impl.h index 45dc30c2c894..6ea122757428 100644 --- a/components/brave_sync/client/brave_sync_client_impl.h +++ b/components/brave_sync/client/brave_sync_client_impl.h @@ -1,9 +1,14 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright 2019 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/. */ -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_CLIENT_IMPL_H -#define BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_CLIENT_IMPL_H +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BRAVE_SYNC_CLIENT_IMPL_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BRAVE_SYNC_CLIENT_IMPL_H_ + +#include +#include +#include #include "brave/components/brave_sync/client/brave_sync_client.h" #include "base/macros.h" @@ -21,7 +26,7 @@ class BraveSyncEventRouter; namespace brave_sync { namespace prefs { - class Prefs; +class Prefs; } using extensions::Extension; @@ -45,7 +50,7 @@ class BraveSyncClientImpl : public BraveSyncClient, void SendFetchSyncRecords( const std::vector &category_names, const base::Time &startAt, const int max_records) override; - void SendFetchSyncDevices() override ; + void SendFetchSyncDevices() override; void SendResolveSyncRecords( const std::string& category_name, std::unique_ptr records) override; @@ -62,7 +67,7 @@ class BraveSyncClientImpl : public BraveSyncClient, friend class ::BraveSyncServiceTest; static void set_for_testing(BraveSyncClient* sync_client); - BraveSyncClientImpl(SyncMessageHandler* handler, Profile* profile); + explicit BraveSyncClientImpl(SyncMessageHandler* handler, Profile* profile); void OnExtensionInitialized() override; void OnSyncEnabledChanged() override; @@ -78,8 +83,6 @@ class BraveSyncClientImpl : public BraveSyncClient, void LoadOrUnloadExtension(bool load); void OnExtensionSystemReady(); - void ClearOrderMap() override; - SyncMessageHandler* handler_; // not owned Profile* profile_; // not owned std::unique_ptr sync_prefs_; @@ -93,6 +96,6 @@ class BraveSyncClientImpl : public BraveSyncClient, DISALLOW_COPY_AND_ASSIGN(BraveSyncClientImpl); }; -} // namespace brave_sync +} // namespace brave_sync -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_CLIENT_IMPL_H +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_BRAVE_SYNC_CLIENT_IMPL_H_ diff --git a/components/brave_sync/client/client_ext_impl_data.cc b/components/brave_sync/client/client_ext_impl_data.cc index 5322044c99b8..f55986a77e38 100644 --- a/components/brave_sync/client/client_ext_impl_data.cc +++ b/components/brave_sync/client/client_ext_impl_data.cc @@ -1,9 +1,13 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright 2019 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/client/client_ext_impl_data.h" +#include +#include + #include "brave/common/extensions/api/brave_sync.h" #include "brave/components/brave_sync/client/client_data.h" #include "brave/components/brave_sync/jslib_messages.h" @@ -11,11 +15,12 @@ namespace brave_sync { -void ConvertConfig(const brave_sync::client_data::Config &config, - extensions::api::brave_sync::Config &config_extension) { - config_extension.api_version = config.api_version; - config_extension.server_url = config.server_url; - config_extension.debug = config.debug; +void ConvertConfig(const brave_sync::client_data::Config& config, + extensions::api::brave_sync::Config* config_extension) { + DCHECK(config_extension); + config_extension->api_version = config.api_version; + config_extension->server_url = config.server_url; + config_extension->debug = config.debug; } std::unique_ptr FromExtSite( @@ -51,7 +56,6 @@ std::unique_ptr FromExtSiteSetting( } CHECK_AND_ASSIGN(zoomLevel, zoom_level); CHECK_AND_ASSIGN(shieldsUp, shields_up); - //DCHECK(false); // site_setting-> = ext_site_setting.ad_control; // site_setting-> = ext_site_setting.cookie_control; CHECK_AND_ASSIGN(safeBrowsing, safe_browsing); @@ -65,6 +69,20 @@ std::unique_ptr FromExtSiteSetting( return site_setting; } +std::unique_ptr> FromExtMetaInfo( + const std::vector& ext_meta_info) { + auto meta_info = std::make_unique>(); + + for (auto& ext_meta : ext_meta_info) { + brave_sync::jslib::MetaInfo meta; + meta.key = ext_meta.key; + meta.value = ext_meta.value; + meta_info->push_back(meta); + } + + return meta_info; +} + std::unique_ptr FromExtBookmark( const extensions::api::brave_sync::Bookmark &ext_bookmark) { auto bookmark = std::make_unique(); @@ -85,6 +103,9 @@ std::unique_ptr FromExtBookmark( if (ext_bookmark.order) { bookmark->order = *ext_bookmark.order; } + if (ext_bookmark.meta_info) { + bookmark->metaInfo = std::move(*FromExtMetaInfo(*ext_bookmark.meta_info)); + } return bookmark; } @@ -96,13 +117,28 @@ std::unique_ptr FromLibSite( ext_site->location = lib_site.location; ext_site->title = lib_site.title; ext_site->custom_title = lib_site.customTitle; - ext_site->last_accessed_time = 0;//lib_site.lastAccessedTime.ToJsTime(); - ext_site->creation_time = 0;//lib_site.creationTime.ToJsTime(); + ext_site->last_accessed_time = 0; // lib_site.lastAccessedTime.ToJsTime(); + ext_site->creation_time = 0; // lib_site.creationTime.ToJsTime(); ext_site->favicon = lib_site.favicon; return ext_site; } +std::unique_ptr> +FromLibMetaInfo(const std::vector& lib_metaInfo) { + auto ext_meta_info = + std::make_unique>(); + + for (auto& metaInfo : lib_metaInfo) { + auto meta_info = std::make_unique(); + meta_info->key = metaInfo.key; + meta_info->value = metaInfo.value; + ext_meta_info->push_back(std::move(*meta_info)); + } + + return ext_meta_info; +} + std::unique_ptr FromLibBookmark( const jslib::Bookmark &lib_bookmark) { auto ext_bookmark = std::make_unique(); @@ -118,14 +154,6 @@ std::unique_ptr FromLibBookmark( new std::string(lib_bookmark.parentFolderObjectId)); } - if (!lib_bookmark.prevObjectId.empty()) { - ext_bookmark->prev_object_id.reset( - new std::vector( - UCharVecFromString(lib_bookmark.prevObjectId))); - ext_bookmark->prev_object_id_str.reset( - new std::string(lib_bookmark.prevObjectId)); - } - if (!lib_bookmark.fields.empty()) { ext_bookmark->fields.reset( new std::vector(lib_bookmark.fields)); @@ -135,11 +163,9 @@ std::unique_ptr FromLibBookmark( ext_bookmark->order.reset(new std::string(lib_bookmark.order)); - ext_bookmark->prev_order.reset(new std::string(lib_bookmark.prevOrder)); - - ext_bookmark->next_order.reset(new std::string(lib_bookmark.nextOrder)); - - ext_bookmark->parent_order.reset(new std::string(lib_bookmark.parentOrder)); + if (!lib_bookmark.metaInfo.empty()) { + ext_bookmark->meta_info = FromLibMetaInfo(lib_bookmark.metaInfo); + } return ext_bookmark; } @@ -153,9 +179,8 @@ std::unique_ptr FromLibSiteSetting( ext_site_setting->zoom_level.reset(new double(lib_site_setting.zoomLevel)); ext_site_setting->shields_up.reset(new bool (lib_site_setting.shieldsUp)); - //ext_site_setting->ad_control = lib_site_setting.adControl; - //ext_site_setting->cookie_control = lib_site_setting.cookieControl; - //DCHECK(false); + // ext_site_setting->ad_control = lib_site_setting.adControl; + // ext_site_setting->cookie_control = lib_site_setting.cookieControl; ext_site_setting->safe_browsing.reset( new bool(lib_site_setting.safeBrowsing)); ext_site_setting->no_script.reset(new bool(lib_site_setting.noScript)); @@ -182,11 +207,10 @@ std::unique_ptr FromLibDevice( return ext_device; } -std::unique_ptr FromLibSyncRecord( - const brave_sync::SyncRecordPtr &lib_record) { +std::unique_ptr FromLibSyncRecord( + const brave_sync::SyncRecordPtr& lib_record) { DCHECK(lib_record); - std::unique_ptr ext_record = - std::make_unique(); + std::unique_ptr ext_record = std::make_unique(); ext_record->action = static_cast(lib_record->action); ext_record->device_id = UCharVecFromString(lib_record->deviceId); @@ -213,14 +237,14 @@ std::unique_ptr FromLibSyncRecord( return ext_record; } -brave_sync::SyncRecordPtr FromExtSyncRecord( - const extensions::api::brave_sync::SyncRecord &ext_record) { - brave_sync::SyncRecordPtr record = std::make_unique(); +brave_sync::SyncRecordPtr FromExtSyncRecord(const SyncRecord& ext_record) { + brave_sync::SyncRecordPtr record = + std::make_unique(); - record->action = ConvertEnum(ext_record.action, - brave_sync::jslib::SyncRecord::Action::A_MIN, - brave_sync::jslib::SyncRecord::Action::A_MAX, - brave_sync::jslib::SyncRecord::Action::A_INVALID); + record->action = ConvertEnum( + ext_record.action, brave_sync::jslib::SyncRecord::Action::A_MIN, + brave_sync::jslib::SyncRecord::Action::A_MAX, + brave_sync::jslib::SyncRecord::Action::A_INVALID); record->deviceId = StrFromUnsignedCharArray(ext_record.device_id); record->objectId = StrFromUnsignedCharArray(ext_record.object_id); @@ -266,21 +290,21 @@ brave_sync::SyncRecordPtr FromExtSyncRecord( void ConvertSyncRecords( const std::vector& ext_records, - std::vector &records) { - DCHECK(records.empty()); + std::vector* records) { + DCHECK(records); + DCHECK(records->empty()); - for (const extensions::api::brave_sync::SyncRecord &ext_record : ext_records) { + for (const auto& ext_record : ext_records) { brave_sync::SyncRecordPtr record = FromExtSyncRecord(ext_record); - records.emplace_back(std::move(record)); + records->emplace_back(std::move(record)); } } void ConvertResolvedPairs( const SyncRecordAndExistingList& records_and_existing_objects, - std::vector& - records_and_existing_objects_ext) { - - DCHECK(records_and_existing_objects_ext.empty()); + std::vector* records_and_existing_objects_ext) { + DCHECK(records_and_existing_objects_ext); + DCHECK(records_and_existing_objects_ext->empty()); for (const SyncRecordAndExistingPtr &src : records_and_existing_objects) { DCHECK(src->first.get() != nullptr); @@ -293,20 +317,20 @@ void ConvertResolvedPairs( dest->local_record = FromLibSyncRecord(src->second); } - records_and_existing_objects_ext.emplace_back(std::move(*dest)); + records_and_existing_objects_ext->emplace_back(std::move(*dest)); } } void ConvertSyncRecordsFromLibToExt( const std::vector& records, - std::vector& records_extension) { - DCHECK(records_extension.empty()); + std::vector* records_extension) { + DCHECK(records_extension); + DCHECK(records_extension->empty()); for (const brave_sync::SyncRecordPtr &src : records) { - std::unique_ptr dest = - FromLibSyncRecord(src); - records_extension.emplace_back(std::move(*dest)); + std::unique_ptr dest = FromLibSyncRecord(src); + records_extension->emplace_back(std::move(*dest)); } } -} // namespace brave_sync +} // namespace brave_sync diff --git a/components/brave_sync/client/client_ext_impl_data.h b/components/brave_sync/client/client_ext_impl_data.h index 20965c7d1e2f..2e5beaeef119 100644 --- a/components/brave_sync/client/client_ext_impl_data.h +++ b/components/brave_sync/client/client_ext_impl_data.h @@ -1,9 +1,10 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright 2019 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/. */ -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_CLIENT_EXT_IMPL_DATA_H -#define BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_CLIENT_EXT_IMPL_DATA_H +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_CLIENT_EXT_IMPL_DATA_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_CLIENT_EXT_IMPL_DATA_H_ #include #include @@ -13,33 +14,38 @@ namespace extensions { namespace api { namespace brave_sync { - struct Config; - struct SyncRecord; - struct RecordAndExistingObject; +struct Config; +struct SyncRecord; +struct RecordAndExistingObject; } } } namespace brave_sync { namespace client_data { - class Config; +class Config; } } namespace brave_sync { -void ConvertConfig(const brave_sync::client_data::Config &config, - extensions::api::brave_sync::Config &config_extension); +using extensions::api::brave_sync::RecordAndExistingObject; +using extensions::api::brave_sync::SyncRecord; -void ConvertSyncRecords(const std::vector &records_extension, - std::vector &records); +void ConvertConfig(const brave_sync::client_data::Config& config, + extensions::api::brave_sync::Config* config_extension); -void ConvertResolvedPairs(const SyncRecordAndExistingList &records_and_existing_objects, - std::vector &records_and_existing_objects_ext); +void ConvertSyncRecords(const std::vector& records_extension, + std::vector* records); -void ConvertSyncRecordsFromLibToExt(const std::vector &records, - std::vector &records_extension); +void ConvertResolvedPairs( + const SyncRecordAndExistingList& records_and_existing_objects, + std::vector* records_and_existing_objects_ext); -} // namespace brave_sync +void ConvertSyncRecordsFromLibToExt( + const std::vector& records, + std::vector* records_extension); -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_CLIENT_EXT_IMPL_DATA_H +} // namespace brave_sync + +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_CLIENT_CLIENT_EXT_IMPL_DATA_H_ diff --git a/components/brave_sync/extension/background.js b/components/brave_sync/extension/background.js index 9e1ca430ed8e..5fabc8824137 100644 --- a/components/brave_sync/extension/background.js +++ b/components/brave_sync/extension/background.js @@ -34,13 +34,9 @@ chrome.braveSync.onResolveSyncRecords.addListener(function(category_name, record if ('localRecord' in cur_rec) { fixupSyncRecordBrowserToExt(cur_rec.serverRecord); fixupSyncRecordBrowserToExt(cur_rec.localRecord); - getOrder(cur_rec.localRecord); - removeLocalMeta(cur_rec.serverRecord); - removeLocalMeta(cur_rec.localRecord); recordsAndExistingObjectsArrArr.push([cur_rec.serverRecord, cur_rec.localRecord]); } else { fixupSyncRecordBrowserToExt(cur_rec.serverRecord); - removeLocalMeta(cur_rec.serverRecord); recordsAndExistingObjectsArrArr.push([cur_rec.serverRecord, null]); } } @@ -51,10 +47,13 @@ chrome.braveSync.onResolveSyncRecords.addListener(function(category_name, record chrome.braveSync.onSendSyncRecords.addListener(function(category_name, records) { // Fixup ids for (var i = 0; i < records.length; ++i) { - // getOrder requires objectIdStr to send back order - getOrder(records[i]); fixupSyncRecordBrowserToExt(records[i]); - removeLocalMeta(records[i]); + // delete meta info for now until all platforms can support + // "Version" and "UniquePosition" of chromium sync proto + if ('bookmark' in records[i]) { + if ('metaInfo' in records[i].bookmark) + delete records[i].bookmark.metaInfo; + } } console.log(`"send-sync-records" category_name=${JSON.stringify(category_name)} records=${JSON.stringify(records)}`); callbackList["send-sync-records"](null, category_name, records); @@ -78,60 +77,12 @@ chrome.braveSync.onLoadClient.addListener(function() { LoadJsLibScript(); }); -chrome.braveSync.onClearOrderMap.addListener(function() { - orderMap = {}; -}); - chrome.braveSync.extensionInitialized(); console.log("chrome.braveSync.extensionInitialized"); //------------------------------------------------------------- -function getOrder(record) { - if ('bookmark' in record) { - if (!record.bookmark.order) { - getBookmarkOrderCallback = (order) => { - record.bookmark.order = order; - if (record.objectId) - orderMap[record.objectId] = order; - if (record.objectIdStr) - chrome.braveSync.saveBookmarkOrder(record.objectIdStr, order); - getBookmarkOrderCallback = null; - } - - var prevOrder = record.bookmark.prevOrder; - var parentOrder = record.bookmark.parentOrder; - if (!prevOrder && orderMap[record.bookmark.prevObjectId]) - prevOrder = orderMap[record.bookmark.prevObjectId]; - if (!parentOrder && orderMap[record.bookmark.parentFolderObjectId]) - parentOrder = orderMap[record.bookmark.parentFolderObjectId]; - console.log(`"get-bookmark-order" prevOrder=${prevOrder}` + - ` nextOrder=${record.bookmark.nextOrder} parentOrder=${parentOrder}`); - callbackList["get-bookmark-order"](null, prevOrder, - record.bookmark.nextOrder, parentOrder); - while(getBookmarkOrderCallback); - } - } -} - -function removeLocalMeta(record) { - if ('bookmark' in record) { - if ('prevObjectId' in record.bookmark) { - delete record.bookmark.prevObjectId; - } - if ('prevOrder' in record.bookmark) { - delete record.bookmark.prevOrder; - } - if ('nextOrder' in record.bookmark) { - delete record.bookmark.nextOrder; - } - if ('parentOrder' in record.bookmark) { - delete record.bookmark.parentOrder; - } - } -} - -function fixupBookmarkFields(category_name, records) { +function fixupBookmarkParentFolderObjectId(category_name, records) { // records[0].bookmark.parentFolderObjectId can be either Uint8Array or Array[] // Uint8Array is expanded to "binary", // Array[] is expanded to "array" of "integer" in schema @@ -139,9 +90,6 @@ function fixupBookmarkFields(category_name, records) { if (category_name == "BOOKMARKS") { for(var i = 0; i < records.length; ++i) { fixupSyncRecordExtToBrowser(records[i]); - // Until brave-sync cannot deal with metaInfo field, this field causes - // "Error at property 'bookmark': Unexpected property: 'metaInfo'" - delete records[i].bookmark.metaInfo; } } } @@ -203,21 +151,6 @@ function fixupSyncRecordExtToBrowser(sync_record) { } delete sync_record.bookmark.parentFolderObjectIdStr; } - if ('prevObjectId' in sync_record.bookmark) { - if (Array.isArray(sync_record.bookmark.prevObjectId)) { - sync_record.bookmark.prevObjectId = new Uint8Array(sync_record.bookmark.prevObjectId); - } else if (sync_record.bookmark.prevObjectId == null || sync_record.bookmark.prevObjectId.length == 0) { - sync_record.bookmark.prevObjectId = new Uint8Array(); - } - } else { - sync_record.bookmark.prevObjectId = new Uint8Array(); - } - if ('prevObjectIdStr' in sync_record.bookmark) { - if (sync_record.bookmark.prevObjectIdStr) { - sync_record.bookmark.prevObjectId = new Uint8Array(IntArrayFromString(sync_record.bookmark.prevObjectIdStr)); - } - delete sync_record.bookmark.prevObjectIdStr; - } } } @@ -261,7 +194,7 @@ class InjectedObject { chrome.braveSync.syncReady(); break; case "get-existing-objects": - fixupBookmarkFields(arg1, arg2); + fixupBookmarkParentFolderObjectId(arg1, arg2); console.log(`"get-existing-objects" category_name=${JSON.stringify(arg1)} records=${JSON.stringify(arg2)} lastRecordTimeStamp=${arg3 ? arg3 : 0} isTruncated=${arg4 != undefined ? arg4 : false} `); chrome.braveSync.getExistingObjects(arg1/*category_name*/, arg2/*records*/, arg3 ? arg3 : 0/*lastRecordTimeStamp*/, arg4 != undefined ? arg4 : false/*isTruncated*/); @@ -275,12 +208,6 @@ class InjectedObject { console.log(`"save-bookmarks-base-order" order=${JSON.stringify(arg1)} `); chrome.braveSync.saveBookmarksBaseOrder(arg1/*order*/); break; - case "save-bookmark-order": - console.log(`"save-bookmark-order" order=${JSON.stringify(arg1)} prevOrder=${JSON.stringify(arg2)} nextOrder=${JSON.stringify(arg3)} parentOrder=${JSON.stringify(arg4)}`); - if (getBookmarkOrderCallback) { - getBookmarkOrderCallback(arg1); - } - break; default: console.log('background.js TAGAB InjectedObject.handleMessage unknown message', message, arg1, arg2, arg3, arg4); console.log('background.js TAGAB message=' + message); @@ -311,7 +238,6 @@ function LoadJsLibScript() { var callbackList = {}; /* message name to callback function */ var getBookmarkOrderCallback = null; -var orderMap = {} if (!self.chrome) { self.chrome = {}; diff --git a/components/brave_sync/jslib_messages.cc b/components/brave_sync/jslib_messages.cc index 9653f63c0004..8f8af5771c10 100644 --- a/components/brave_sync/jslib_messages.cc +++ b/components/brave_sync/jslib_messages.cc @@ -1,7 +1,12 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright 2019 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/jslib_messages.h" + +#include + #include "brave/components/brave_sync/values_conv.h" #include "base/logging.h" #include "base/values.h" @@ -26,6 +31,23 @@ std::unique_ptr Site::Clone(const Site& site) { return std::make_unique(site); } +std::string Site::TryGetNonEmptyTitle() const { + return !title.empty() ? title : customTitle; +} + +MetaInfo::MetaInfo() = default; + +MetaInfo::MetaInfo(const MetaInfo& metaInfo) { + key = metaInfo.key; + value = metaInfo.value; +} + +MetaInfo::~MetaInfo() = default; + +std::unique_ptr MetaInfo::Clone(const MetaInfo& metaInfo) { + return std::make_unique(metaInfo); +} + Bookmark::Bookmark() : isFolder(false), hideInToolbar(false) {} Bookmark::Bookmark(const Bookmark& bookmark) { @@ -35,12 +57,13 @@ Bookmark::Bookmark(const Bookmark& bookmark) { fields = bookmark.fields; hideInToolbar = bookmark.hideInToolbar; order = bookmark.order; + metaInfo = bookmark.metaInfo; } Bookmark::~Bookmark() = default; std::unique_ptr Bookmark::Clone(const Bookmark& bookmark) { - return std::make_unique(bookmark); + return std::make_unique(bookmark); } SiteSetting::SiteSetting() : zoomLevel(1.0f), shieldsUp(true), @@ -52,21 +75,22 @@ SiteSetting::SiteSetting() : zoomLevel(1.0f), shieldsUp(true), SiteSetting::~SiteSetting() = default; -std::unique_ptr SiteSetting::Clone(const SiteSetting& site_setting) { - auto ret_val = std::make_unique(); - ret_val->hostPattern = site_setting.hostPattern; - ret_val->zoomLevel = site_setting.zoomLevel; - ret_val->shieldsUp = site_setting.shieldsUp; - ret_val->adControl = site_setting.adControl; - ret_val->cookieControl = site_setting.cookieControl; - ret_val->safeBrowsing = site_setting.safeBrowsing; - ret_val->noScript = site_setting.noScript; - ret_val->httpsEverywhere = site_setting.httpsEverywhere; - ret_val->fingerprintingProtection = site_setting.fingerprintingProtection; - ret_val->ledgerPayments = site_setting.ledgerPayments; - ret_val->ledgerPaymentsShown = site_setting.ledgerPaymentsShown; - ret_val->fields = site_setting.fields; - return ret_val; +std::unique_ptr SiteSetting::Clone( + const SiteSetting& site_setting) { + auto ret_val = std::make_unique(); + ret_val->hostPattern = site_setting.hostPattern; + ret_val->zoomLevel = site_setting.zoomLevel; + ret_val->shieldsUp = site_setting.shieldsUp; + ret_val->adControl = site_setting.adControl; + ret_val->cookieControl = site_setting.cookieControl; + ret_val->safeBrowsing = site_setting.safeBrowsing; + ret_val->noScript = site_setting.noScript; + ret_val->httpsEverywhere = site_setting.httpsEverywhere; + ret_val->fingerprintingProtection = site_setting.fingerprintingProtection; + ret_val->ledgerPayments = site_setting.ledgerPayments; + ret_val->ledgerPaymentsShown = site_setting.ledgerPaymentsShown; + ret_val->fields = site_setting.fields; + return ret_val; } Device::Device() = default; @@ -74,9 +98,9 @@ Device::Device() = default; Device::~Device() = default; std::unique_ptr Device::Clone(const Device& device) { - auto ret_val = std::make_unique(); - ret_val->name = device.name; - return ret_val; + auto ret_val = std::make_unique(); + ret_val->name = device.name; + return ret_val; } SyncRecord::SyncRecord() : action(SyncRecord::Action::A_INVALID) {} @@ -84,25 +108,25 @@ SyncRecord::SyncRecord() : action(SyncRecord::Action::A_INVALID) {} SyncRecord::~SyncRecord() = default; std::unique_ptr SyncRecord::Clone(const SyncRecord& record) { - auto ret_val = std::make_unique(); + auto ret_val = std::make_unique(); - ret_val->action = record.action; - ret_val->deviceId = record.deviceId; - ret_val->objectId = record.objectId; - ret_val->objectData = record.objectData; - if (record.has_bookmark()) { - ret_val->SetBookmark(Bookmark::Clone(record.GetBookmark())); - } else if (record.has_historysite()) { - ret_val->SetHistorySite(Site::Clone(record.GetHistorySite())); - } else if (record.has_sitesetting()) { - ret_val->SetSiteSetting(SiteSetting::Clone(record.GetSiteSetting())); - } else if (record.has_device()) { - ret_val->SetDevice(Device::Clone(record.GetDevice())); - } + ret_val->action = record.action; + ret_val->deviceId = record.deviceId; + ret_val->objectId = record.objectId; + ret_val->objectData = record.objectData; + if (record.has_bookmark()) { + ret_val->SetBookmark(Bookmark::Clone(record.GetBookmark())); + } else if (record.has_historysite()) { + ret_val->SetHistorySite(Site::Clone(record.GetHistorySite())); + } else if (record.has_sitesetting()) { + ret_val->SetSiteSetting(SiteSetting::Clone(record.GetSiteSetting())); + } else if (record.has_device()) { + ret_val->SetDevice(Device::Clone(record.GetDevice())); + } - ret_val->syncTimestamp = record.syncTimestamp; + ret_val->syncTimestamp = record.syncTimestamp; - return ret_val; + return ret_val; } bool SyncRecord::has_bookmark() const { @@ -141,26 +165,35 @@ const Device& SyncRecord::GetDevice() const { return *device_.get(); } +Bookmark* SyncRecord::mutable_bookmark() { + DCHECK(has_bookmark()); + return bookmark_.get(); +} + void SyncRecord::SetBookmark(std::unique_ptr bookmark) { - DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && !has_device()); + DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && + !has_device()); bookmark_ = std::move(bookmark); } void SyncRecord::SetHistorySite(std::unique_ptr history_site) { - DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && !has_device()); + DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && + !has_device()); history_site_ = std::move(history_site); } void SyncRecord::SetSiteSetting(std::unique_ptr site_setting) { - DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && !has_device()); + DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && + !has_device()); site_setting_ = std::move(site_setting); } void SyncRecord::SetDevice(std::unique_ptr device) { - DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && !has_device()); + DCHECK(!has_bookmark() && !has_historysite() && !has_sitesetting() && + !has_device()); device_ = std::move(device); } -} // jslib +} // namespace jslib -} // namespace brave_sync +} // namespace brave_sync diff --git a/components/brave_sync/jslib_messages.h b/components/brave_sync/jslib_messages.h index 9fe963eb3dbe..4e96013d3003 100644 --- a/components/brave_sync/jslib_messages.h +++ b/components/brave_sync/jslib_messages.h @@ -1,14 +1,16 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright 2019 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/. */ -#ifndef H_BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_JSLIB_MESSAGES_H -#define H_BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_JSLIB_MESSAGES_H + +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_JSLIB_MESSAGES_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_JSLIB_MESSAGES_H_ #include #include #include -#include +#include "base/time/time.h" namespace brave_sync { @@ -16,19 +18,24 @@ namespace jslib { // Simple C++ structures to work with messages from sync lib // Since it is not possible to use sync lib C++ protobuf generated by reasons: -// 1) Chromium everywhere uses `syntax = "proto2";`, sync-lib - `syntax = "proto3";` -// 2) forcing to use version 3 makes to have a deps "//third_party/protobuf:protobuf_full" : +// 1) Chromium everywhere uses `syntax = "proto2";`, +// sync-lib - `syntax = "proto3";` +// 2) forcing to use version 3 makes to have a deps +// "//third_party/protobuf:protobuf_full" : // marked `Do not use in Chrome code.` in src/third_party/protobuf/BUILD.gn -// 3) even with a depth of a deps "//third_party/protobuf:protobuf_full" there are questions -// how to convert json -> protobuf class, not all of fields were converted +// 3) even with a depth of a deps "//third_party/protobuf:protobuf_full" +// there are questions how to convert json -> protobuf class, +// not all of fields were converted class Site { -public: + public: Site(); Site(const Site& site); ~Site(); static std::unique_ptr Clone(const Site& site); + std::string TryGetNonEmptyTitle() const; + std::string location; std::string title; std::string customTitle; @@ -37,8 +44,19 @@ class Site { std::string favicon; }; +class MetaInfo { + public: + MetaInfo(); + MetaInfo(const MetaInfo& metaInfo); + ~MetaInfo(); + static std::unique_ptr Clone(const MetaInfo& metaInfo); + + std::string key; + std::string value; +}; + class Bookmark { -public: + public: Bookmark(); Bookmark(const Bookmark& bookmark); ~Bookmark(); @@ -46,18 +64,15 @@ class Bookmark { Site site; bool isFolder; - std::string parentFolderObjectId; // bytes - std::string prevObjectId; // bytes + std::string parentFolderObjectId; // bytes std::vector fields; bool hideInToolbar; std::string order; - std::string prevOrder; - std::string nextOrder; - std::string parentOrder; + std::vector metaInfo; }; class SiteSetting { -public: + public: SiteSetting(); ~SiteSetting(); static std::unique_ptr Clone(const SiteSetting& site_setting); @@ -93,7 +108,7 @@ class SiteSetting { }; class Device { -public: + public: Device(); ~Device(); static std::unique_ptr Clone(const Device& device); @@ -102,7 +117,7 @@ class Device { class SyncRecord { -public: + public: SyncRecord(); ~SyncRecord(); @@ -118,8 +133,8 @@ class SyncRecord { }; Action action; - std::string deviceId; // bytes - std::string objectId; // bytes + std::string deviceId; // bytes + std::string objectId; // bytes std::string objectData; @@ -131,6 +146,7 @@ class SyncRecord { const Site& GetHistorySite() const; const SiteSetting& GetSiteSetting() const; const Device& GetDevice() const; + Bookmark* mutable_bookmark(); void SetBookmark(std::unique_ptr bookmark); void SetHistorySite(std::unique_ptr history_site); @@ -138,7 +154,8 @@ class SyncRecord { void SetDevice(std::unique_ptr device); base::Time syncTimestamp; -private: + + private: std::unique_ptr bookmark_; std::unique_ptr history_site_; std::unique_ptr site_setting_; @@ -149,4 +166,4 @@ class SyncRecord { } // namespace brave_sync -#endif // H_BRAVE_COMPONENTS_BRAVE_SYNC_BRAVE_SYNC_JSLIB_MESSAGES_H +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_JSLIB_MESSAGES_H_ diff --git a/components/brave_sync/jslib_messages_fwd.h b/components/brave_sync/jslib_messages_fwd.h index 43274a279d37..181848bcbf06 100644 --- a/components/brave_sync/jslib_messages_fwd.h +++ b/components/brave_sync/jslib_messages_fwd.h @@ -1,10 +1,17 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public +/* Copyright 2019 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/. */ #ifndef BRAVE_COMPONENTS_BRAVE_SYNC_JSLIB_MESSAGES_FWD_H_ #define BRAVE_COMPONENTS_BRAVE_SYNC_JSLIB_MESSAGES_FWD_H_ +#include +#include +#include + +#include "base/callback.h" +#include "base/synchronization/waitable_event.h" #include "build/build_config.h" // TODO(darkdh): forward declaration with unique_ptr on Windows @@ -18,6 +25,10 @@ class SyncRecord; } #endif +namespace syncer { +class Syncer; +} // namespace syncer + namespace brave_sync { typedef std::unique_ptr SyncRecordPtr; @@ -28,6 +39,12 @@ typedef std::unique_ptr SyncRecordAndExistingPtr; typedef std::vector SyncRecordAndExistingList; using Uint8Array = std::vector; +using GetRecordsCallback = + base::OnceCallback)>; +using NudgeSyncCycleDelegate = base::RepeatingCallback; +using PollSyncCycleDelegate = + base::RepeatingCallback; } // namespace brave_sync diff --git a/components/brave_sync/model/change_processor.h b/components/brave_sync/model/change_processor.h deleted file mode 100644 index 3a74711a0bf9..000000000000 --- a/components/brave_sync/model/change_processor.h +++ /dev/null @@ -1,47 +0,0 @@ -/* 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/. */ - -#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_MODEL_CHANGE_PROCESSOR_H_ -#define BRAVE_COMPONENTS_BRAVE_SYNC_MODEL_CHANGE_PROCESSOR_H_ - -#include "base/macros.h" -#include "base/time/time.h" -#include "brave/components/brave_sync/client/client_ext_impl_data.h" - -namespace brave_sync { - -class ChangeProcessor { - public: - virtual ~ChangeProcessor() = default; - - // start processing local changes - virtual void Start() = 0; - // stop processing local changes - virtual void Stop() = 0; - - // reset all sync data, but do not delete local records - // 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; - - // get all local sync data matching `records` and return the matched pair - // in `records_and_existing_objects` - virtual void GetAllSyncData( - const std::vector>& records, - SyncRecordAndExistingList* records_and_existing_objects) = 0; - // update local data from `records` - virtual void ApplyChangesFromSyncModel(const RecordsList& records) = 0; - // send any new records that have not yet been synced to the server - // for each record, if the last synced time is less than - // `unsynced_send_interval` then skip sending it this time - virtual void SendUnsynced(base::TimeDelta unsynced_send_interval) = 0; -}; - -} // namespace brave_sync - -#endif // BRAVE_COMPONENTS_BRAVE_SYNC_MODEL_CHANGE_PROCESSOR_H_ diff --git a/components/brave_sync/public/brave_profile_sync_service.h b/components/brave_sync/public/brave_profile_sync_service.h new file mode 100644 index 000000000000..983b424b1ff8 --- /dev/null +++ b/components/brave_sync/public/brave_profile_sync_service.h @@ -0,0 +1,38 @@ +/* Copyright 2019 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/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_PUBLIC_BRAVE_PROFILE_SYNC_SERVICE_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_PUBLIC_BRAVE_PROFILE_SYNC_SERVICE_H_ + +#include + +#include "brave/components/brave_sync/jslib_messages_fwd.h" +#include "components/sync/driver/profile_sync_service.h" + +namespace base { +class WaitableEvent; +} + +namespace brave_sync { + +class BraveSyncService; + +class BraveProfileSyncService : public syncer::ProfileSyncService { + public: + explicit BraveProfileSyncService(InitParams init_params) + : syncer::ProfileSyncService(std::move(init_params)) {} + ~BraveProfileSyncService() override {} + + virtual bool IsBraveSyncEnabled() const = 0; + virtual void OnNudgeSyncCycle(brave_sync::RecordsListPtr records_list) = 0; + virtual void OnPollSyncCycle(brave_sync::GetRecordsCallback cb, + base::WaitableEvent* wevent) = 0; + + virtual BraveSyncService* GetSyncService() const = 0; +}; + +} // namespace brave_sync + +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_PUBLIC_BRAVE_PROFILE_SYNC_SERVICE_H_ diff --git a/components/brave_sync/syncer_helper.cc b/components/brave_sync/syncer_helper.cc new file mode 100644 index 000000000000..fd3450c12b7c --- /dev/null +++ b/components/brave_sync/syncer_helper.cc @@ -0,0 +1,154 @@ +/* Copyright 2019 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/syncer_helper.h" + +#include "base/strings/string_number_conversions.h" +#include "brave/components/brave_sync/bookmark_order_util.h" +#include "brave/components/brave_sync/tools.h" +#include "components/bookmarks/browser/bookmark_model.h" + +namespace brave_sync { +namespace { + +void SetOrder(bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node, + const std::string& parent_order) { + DCHECK(!parent_order.empty()); + int index = node->parent()->GetIndexOf(node); + + bookmarks::BookmarkNode* parent = + const_cast(node->parent()); + + auto* prev_node = index == 0 ? nullptr : parent->GetChild(index - 1); + auto* next_node = index == parent->child_count() - 1 + ? nullptr + : parent->GetChild(index + 1); + + std::string prev_order; + std::string next_order; + if (prev_node) + prev_node->GetMetaInfo("order", &prev_order); + + if (next_node) + next_node->GetMetaInfo("order", &next_order); + + std::string order = + brave_sync::GetOrder(prev_order, next_order, parent_order); + model->SetNodeMetaInfo(node, "order", order); +} + +uint64_t GetIndexByOrder(const std::string& record_order) { + uint64_t index = 0; + size_t last_dot_index = record_order.rfind("."); + DCHECK(last_dot_index != std::string::npos); + std::string last_digit = record_order.substr(last_dot_index + 1); + bool result = base::StringToUint64(last_digit, &index); + --index; + DCHECK_GE(index, 0u); + DCHECK(result); + return index; +} + +} // namespace + +uint64_t GetIndexByCompareOrderStartFrom(const bookmarks::BookmarkNode* parent, + const bookmarks::BookmarkNode* src, + int index) { + std::string src_order; + src->GetMetaInfo("order", &src_order); + DCHECK(!src_order.empty()); + DCHECK_GE(index, 0); + bool use_order = true; // If false use object_id + std::string src_object_id; + while (index < parent->child_count()) { + const bookmarks::BookmarkNode* node = parent->GetChild(index); + if (src->id() == node->id()) { + // We reached ourselves, no sense to go further, because we know all + // unsorted elements are in the end + return index; + } + + if (use_order) { + std::string node_order; + node->GetMetaInfo("order", &node_order); + if (!node_order.empty() && + brave_sync::CompareOrder(src_order, node_order)) { + return index; + } + + if (src_order == node_order) { + use_order = false; + } + } + + if (!use_order) { + if (src_object_id.empty()) { + src->GetMetaInfo("object_id", &src_object_id); + } + + std::string node_object_id; + node->GetMetaInfo("object_id", &node_object_id); + + if (src_object_id < node_object_id) { + return index; + } + } + ++index; + } + return index; +} + +void AddBraveMetaInfo(const bookmarks::BookmarkNode* node, + bookmarks::BookmarkModel* model) { + std::string parent_order; + node->parent()->GetMetaInfo("order", &parent_order); + SetOrder(model, node, parent_order); + + std::string object_id; + node->GetMetaInfo("object_id", &object_id); + // newly created node + if (object_id.empty()) { + object_id = tools::GenerateObjectId(); + } + model->SetNodeMetaInfo(node, "object_id", object_id); + + std::string parent_object_id; + node->parent()->GetMetaInfo("object_id", &parent_object_id); + model->SetNodeMetaInfo(node, "parent_object_id", parent_object_id); + + std::string sync_timestamp; + node->GetMetaInfo("sync_timestamp", &sync_timestamp); + if (sync_timestamp.empty()) { + sync_timestamp = std::to_string(base::Time::Now().ToJsTime()); + model->SetNodeMetaInfo(node, "sync_timestamp", sync_timestamp); + } + DCHECK(!sync_timestamp.empty()); +} + +uint64_t GetIndex(const bookmarks::BookmarkNode* parent, + const bookmarks::BookmarkNode* src) { + DCHECK(parent); + DCHECK(src); + int index = 0; + std::string src_order; + src->GetMetaInfo("order", &src_order); + DCHECK(!src_order.empty()); + index = GetIndexByOrder(src_order); + if (index < parent->child_count()) { + const bookmarks::BookmarkNode* node = parent->GetChild(index); + if (node) { + std::string node_order; + node->GetMetaInfo("order", &node_order); + + DCHECK(!node_order.empty()); + if (CompareOrder(node_order, src_order)) + return index + 1; + } + } + return index; +} + +} // namespace brave_sync diff --git a/components/brave_sync/syncer_helper.h b/components/brave_sync/syncer_helper.h new file mode 100644 index 000000000000..24a288dff0b2 --- /dev/null +++ b/components/brave_sync/syncer_helper.h @@ -0,0 +1,32 @@ +/* Copyright 2019 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/. */ + +#ifndef BRAVE_COMPONENTS_BRAVE_SYNC_SYNCER_HELPER_H_ +#define BRAVE_COMPONENTS_BRAVE_SYNC_SYNCER_HELPER_H_ + +#include +#include + +namespace bookmarks { +class BookmarkModel; +class BookmarkNode; +} // namespace bookmarks + +namespace brave_sync { + +void AddBraveMetaInfo(const bookmarks::BookmarkNode* node, + bookmarks::BookmarkModel* bookmark_model); + +// |src| is the node which is about to be inserted into |parent| +uint64_t GetIndex(const bookmarks::BookmarkNode* parent, + const bookmarks::BookmarkNode* src); + +uint64_t GetIndexByCompareOrderStartFrom(const bookmarks::BookmarkNode* parent, + const bookmarks::BookmarkNode* src, + int index); + +} // namespace brave_sync + +#endif // BRAVE_COMPONENTS_BRAVE_SYNC_SYNCER_HELPER_H_ diff --git a/components/brave_sync/syncer_helper_unittest.cc b/components/brave_sync/syncer_helper_unittest.cc new file mode 100644 index 000000000000..edeb4d2e1d13 --- /dev/null +++ b/components/brave_sync/syncer_helper_unittest.cc @@ -0,0 +1,440 @@ +/* Copyright 2019 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 +#include +#include +#include + +#include "base/files/scoped_temp_dir.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "brave/components/brave_sync/syncer_helper.h" +#include "brave/components/brave_sync/test_util.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/browser/bookmark_utils.h" +#include "components/bookmarks/common/bookmark_pref_names.h" +#include "components/bookmarks/test/test_bookmark_client.h" +#include "components/prefs/pref_service.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::AtLeast; + +using bookmarks::BookmarkClient; +using bookmarks::BookmarkModel; +using bookmarks::BookmarkNode; + +namespace brave_sync { + +namespace { + +// |node| is near the end in parent +void RepositionRespectOrder(bookmarks::BookmarkModel* bookmark_model, + const bookmarks::BookmarkNode* node) { + const bookmarks::BookmarkNode* parent = node->parent(); + int index = GetIndexByCompareOrderStartFrom(parent, node, 0); + bookmark_model->Move(node, parent, index); +} + +} // namespace + +class SyncerHelperTest : public testing::Test { + public: + SyncerHelperTest() {} + ~SyncerHelperTest() override {} + + protected: + void SetUp() override { + EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); + + profile_ = CreateBraveSyncProfile(temp_dir_.GetPath()); + EXPECT_TRUE(profile_.get() != NULL); + + BookmarkModelFactory::GetInstance()->SetTestingFactory( + profile_.get(), base::BindRepeating(&BuildFakeBookmarkModelForTests)); + + model_ = BookmarkModelFactory::GetForBrowserContext( + Profile::FromBrowserContext(profile_.get())); + + EXPECT_NE(bookmark_client(), nullptr); + EXPECT_NE(model(), nullptr); + + // SetPermanentNodesOrder + model_->SetNodeMetaInfo(model_->bookmark_bar_node(), "order", "1.0.1"); + + model_->SetNodeMetaInfo(model_->other_node(), "order", "1.0.2"); + } + + void TearDown() override { profile_.reset(); } + + BookmarkClient* bookmark_client() { return model_->client(); } + BookmarkModel* model() { return model_; } + + private: + // Need this as a very first member to run tests in UI thread + // When this is set, class should not install any other MessageLoops, like + // base::test::ScopedTaskEnvironment + content::TestBrowserThreadBundle thread_bundle_; + + BookmarkModel* model_; // Not owns + std::unique_ptr profile_; + base::ScopedTempDir temp_dir_; +}; + +TEST_F(SyncerHelperTest, AddBraveMetaInfoCreateOrUpdate) { + std::string order; + std::string sync_timestamp; + const auto* folder1 = model()->AddFolder(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("Folder1")); + AddBraveMetaInfo(folder1, model()); + folder1->GetMetaInfo("order", &order); + EXPECT_EQ(order, "1.0.1.1"); + std::string folder1_id; + folder1->GetMetaInfo("object_id", &folder1_id); + EXPECT_TRUE(!folder1_id.empty()); + std::string folder1_parent_id; + folder1->GetMetaInfo("parent_object_id", &folder1_parent_id); + EXPECT_TRUE(folder1_parent_id.empty()); + folder1->GetMetaInfo("sync_timestamp", &sync_timestamp); + EXPECT_TRUE(!sync_timestamp.empty()); + + const auto* node_a = model()->AddURL( + folder1, 0, base::ASCIIToUTF16("A.com - title"), GURL("https://a.com/")); + order.clear(); + sync_timestamp.clear(); + AddBraveMetaInfo(node_a, model()); + node_a->GetMetaInfo("order", &order); + EXPECT_EQ(order, "1.0.1.1.1"); + std::string node_a_id; + node_a->GetMetaInfo("object_id", &node_a_id); + EXPECT_TRUE(!node_a_id.empty()); + std::string node_a_parent_id; + node_a->GetMetaInfo("parent_object_id", &node_a_parent_id); + EXPECT_EQ(node_a_parent_id, folder1_id); + node_a->GetMetaInfo("sync_timestamp", &sync_timestamp); + EXPECT_TRUE(!sync_timestamp.empty()); + + // Update + order.clear(); + node_a_id.clear(); + node_a_parent_id.clear(); + model()->SetURL(node_a, GURL("https://a-m.com/")); + AddBraveMetaInfo(node_a, model()); + node_a->GetMetaInfo("order", &order); + EXPECT_EQ(order, "1.0.1.1.1"); + node_a->GetMetaInfo("object_id", &node_a_id); + EXPECT_TRUE(!node_a_id.empty()); + node_a->GetMetaInfo("parent_object_id", &node_a_parent_id); + EXPECT_EQ(node_a_parent_id, folder1_id); + std::string new_sync_timestamp; + node_a->GetMetaInfo("sync_timestamp", &new_sync_timestamp); + EXPECT_EQ(new_sync_timestamp, sync_timestamp); +} + +TEST_F(SyncerHelperTest, AddBraveMetaInfoNodeMoved) { + const auto* folder1 = model()->AddFolder(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("Folder1")); + AddBraveMetaInfo(folder1, model()); + const auto* node_a = model()->AddURL( + folder1, 0, base::ASCIIToUTF16("A.com - title"), GURL("https://a.com/")); + AddBraveMetaInfo(node_a, model()); + model()->Move(node_a, model()->bookmark_bar_node(), 1); + AddBraveMetaInfo(node_a, model()); + + std::string order; + node_a->GetMetaInfo("order", &order); + EXPECT_EQ(order, "1.0.1.2"); + std::string node_a_id; + node_a->GetMetaInfo("object_id", &node_a_id); + EXPECT_TRUE(!node_a_id.empty()); + std::string node_a_parent_id; + node_a->GetMetaInfo("parent_object_id", &node_a_parent_id); + EXPECT_TRUE(node_a_parent_id.empty()); + std::string sync_timestamp; + node_a->GetMetaInfo("sync_timestamp", &sync_timestamp); + EXPECT_TRUE(!sync_timestamp.empty()); +} + +TEST_F(SyncerHelperTest, AddBraveMetaInfoNodeChildrenReordered) { + const auto* node_a = model()->AddURL(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("A.com - title"), + GURL("https://a.com/")); + AddBraveMetaInfo(node_a, model()); + const auto* node_b = model()->AddURL(model()->bookmark_bar_node(), 1, + base::ASCIIToUTF16("B.com - title"), + GURL("https://b.com/")); + AddBraveMetaInfo(node_b, model()); + const auto* node_c = model()->AddURL(model()->bookmark_bar_node(), 2, + base::ASCIIToUTF16("C.com - title"), + GURL("https://c.com/")); + AddBraveMetaInfo(node_c, model()); + + // Expecting to have initially: + // 'Bookmarks Bar' 1.0.1 + // |-A.com 1.0.1.1 + // |-B.com 1.0.1.2 + // |-C.com 1.0.1.3 + + std::string order_a; + std::string order_b; + std::string order_c; + node_a->GetMetaInfo("order", &order_a); + EXPECT_EQ(order_a, "1.0.1.1"); + node_b->GetMetaInfo("order", &order_b); + EXPECT_EQ(order_b, "1.0.1.2"); + node_c->GetMetaInfo("order", &order_c); + EXPECT_EQ(order_c, "1.0.1.3"); + + model()->Move(node_c, model()->bookmark_bar_node(), 0); + AddBraveMetaInfo(node_c, model()); + + // After move to have: + // 'Bookmarks Bar' 1.0.1 + // |-C.com 1.0.1.0.1 + // |-A.com 1.0.1.1 + // |-B.com 1.0.1.2 + + order_a.clear(); + order_b.clear(); + order_c.clear(); + + node_a->GetMetaInfo("order", &order_a); + EXPECT_EQ(order_a, "1.0.1.1"); + node_b->GetMetaInfo("order", &order_b); + EXPECT_EQ(order_b, "1.0.1.2"); + node_c->GetMetaInfo("order", &order_c); + EXPECT_EQ(order_c, "1.0.1.0.1"); +} + +TEST_F(SyncerHelperTest, AddBraveMetaInfoNodeMovedReordered) { + const auto* node_a = model()->AddURL(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("A.com - title"), + GURL("https://a.com/")); + AddBraveMetaInfo(node_a, model()); + const auto* folder1 = model()->AddFolder(model()->bookmark_bar_node(), 1, + base::ASCIIToUTF16("Folder1")); + AddBraveMetaInfo(folder1, model()); + const auto* node_b = model()->AddURL( + folder1, 0, base::ASCIIToUTF16("B.com - title"), GURL("https://b.com/")); + AddBraveMetaInfo(node_b, model()); + const auto* node_c = model()->AddURL( + folder1, 1, base::ASCIIToUTF16("C.com - title"), GURL("https://c.com/")); + AddBraveMetaInfo(node_c, model()); + + // Expecting here to have: + // 'Bookmarks Bar' 1.0.1 + // |-A.com 1.0.1.1 + // |-Folder1 1.0.1.2 + // |-B.com 1.0.1.2.1 + // |-C.com 1.0.1.2.2 + + std::string order_a; + std::string order_b; + std::string order_c; + std::string order_folder1; + node_a->GetMetaInfo("order", &order_a); + EXPECT_EQ(order_a, "1.0.1.1"); + node_b->GetMetaInfo("order", &order_b); + EXPECT_EQ(order_b, "1.0.1.2.1"); + node_c->GetMetaInfo("order", &order_c); + EXPECT_EQ(order_c, "1.0.1.2.2"); + folder1->GetMetaInfo("order", &order_folder1); + EXPECT_EQ(order_folder1, "1.0.1.2"); + + model()->Move(node_a, folder1, 0); + AddBraveMetaInfo(node_a, model()); + + order_a.clear(); + order_b.clear(); + order_c.clear(); + order_folder1.clear(); + + // After move expecting have: + // 'Bookmarks Bar' 1.0.1 (kept) + // |-Folder1 1.0.1.2 (kept) + // |-A.com 1.0.1.2.0.1 (re-calculated) + // |-B.com 1.0.1.2.1 (kept) + // |-C.com 1.0.1.2.2 (kept) + + node_a->GetMetaInfo("order", &order_a); + EXPECT_EQ(order_a, "1.0.1.2.0.1"); + node_b->GetMetaInfo("order", &order_b); + EXPECT_EQ(order_b, "1.0.1.2.1"); + node_c->GetMetaInfo("order", &order_c); + EXPECT_EQ(order_c, "1.0.1.2.2"); + folder1->GetMetaInfo("order", &order_folder1); + EXPECT_EQ(order_folder1, "1.0.1.2"); +} + +TEST_F(SyncerHelperTest, GetIndexInPermanentNodes) { + BookmarkNode node(GURL("https://brave.com")); + node.SetMetaInfo("order", "1.0.1.1"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 0u); + + node.SetMetaInfo("order", "1.0.2.1"); + EXPECT_EQ(GetIndex(model()->other_node(), &node), 0u); + + const auto* node_a = + model()->AddURL(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("a.com"), GURL("https://a.com/")); + // compare device id + model()->SetNodeMetaInfo(node_a, "order", "1.1.1.1"); + node.SetMetaInfo("order", "1.0.1.1"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 0u); + model()->SetNodeMetaInfo(node_a, "order", "1.0.1.1"); + node.SetMetaInfo("order", "1.1.1.1"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 1u); + + // compare platform id + model()->SetNodeMetaInfo(node_a, "order", "2.0.1.1"); + node.SetMetaInfo("order", "1.0.1.1"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 0u); + model()->SetNodeMetaInfo(node_a, "order", "1.0.1.1"); + node.SetMetaInfo("order", "2.0.1.1"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 1u); +} + +TEST_F(SyncerHelperTest, GetIndexMoreChildren) { + for (int i = 0; i < 10; ++i) { + const auto* node_a = + model()->AddURL(model()->bookmark_bar_node(), i, + base::ASCIIToUTF16("a.com"), GURL("https://a.com/")); + std::string order = "1.1.1." + base::NumberToString(i); + model()->SetNodeMetaInfo(node_a, "order", order); + } + // inserted as 10th child + BookmarkNode node(GURL("https://brave.com")); + node.SetMetaInfo("order", "1.0.1.10"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 9u); + node.SetMetaInfo("order", "1.1.1.10"); + EXPECT_EQ(GetIndex(model()->bookmark_bar_node(), &node), 10u); +} + +TEST_F(SyncerHelperTest, GetIndexInFolder) { + const auto* folder1 = model()->AddFolder(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("Folder1")); + model()->SetNodeMetaInfo(folder1, "order", "1.0.1.1"); + BookmarkNode node(GURL("https://brave.com")); + node.SetMetaInfo("order", "1.0.1.1.1"); + EXPECT_EQ(GetIndex(folder1, &node), 0u); + + // appended at the end + const auto* node_a = model()->AddURL(folder1, 0, base::ASCIIToUTF16("a.com"), + GURL("https://a.com/")); + model()->SetNodeMetaInfo(node_a, "order", "1.0.1.1.1"); + node.SetMetaInfo("order", "1.0.1.1.2"); + EXPECT_EQ(GetIndex(folder1, &node), 1u); +} + +TEST_F(SyncerHelperTest, SameOrderBookmarksSordetByObjectIdFull3) { + // This test emulates folowing STR + // 1. on device A create bookmarks A1.com and A2.com + // 2. on device B create bookmarks B1.com and B2.com + // 3. create sync chain on device A and connect device B with a codephrase + // 4. wait for bookmarks will be synchromized between device A and B + // 5. on device A in Add bookmark dialog enter Name A3.com, URL A3.com, + // but dont press Save button + // 6. repeat pt 5 on device B, for B3.com + // 7. press Save button on devices A and B + // Expected bookmarks on devices A and B are sorted in the same way + const auto* node_a1 = + model()->AddURL(model()->bookmark_bar_node(), 0, + base::ASCIIToUTF16("A1.com"), GURL("https://a1.com/")); + AddBraveMetaInfo(node_a1, model()); + const auto* node_a2 = + model()->AddURL(model()->bookmark_bar_node(), 1, + base::ASCIIToUTF16("A2.com"), GURL("https://a2.com/")); + AddBraveMetaInfo(node_a2, model()); + const auto* node_b1 = + model()->AddURL(model()->bookmark_bar_node(), 2, + base::ASCIIToUTF16("B1.com"), GURL("https://b1.com/")); + AddBraveMetaInfo(node_b1, model()); + const auto* node_b2 = + model()->AddURL(model()->bookmark_bar_node(), 3, + base::ASCIIToUTF16("B2.com"), GURL("https://b2.com/")); + AddBraveMetaInfo(node_b2, model()); + + // Expect b1 and b2 no need to move + uint64_t index_to_move_b1 = + GetIndexByCompareOrderStartFrom(model()->bookmark_bar_node(), node_b1, 0); + EXPECT_EQ(index_to_move_b1, 2u); + + uint64_t index_to_move_b2 = + GetIndexByCompareOrderStartFrom(model()->bookmark_bar_node(), node_b2, 0); + EXPECT_EQ(index_to_move_b2, 3u); + + const auto* node_a3 = + model()->AddURL(model()->bookmark_bar_node(), 4, + base::ASCIIToUTF16("A3.com"), GURL("https://a3.com/")); + AddBraveMetaInfo(node_a3, model()); + const auto* node_b3 = + model()->AddURL(model()->bookmark_bar_node(), 5, + base::ASCIIToUTF16("B3.com"), GURL("https://b3.com/")); + AddBraveMetaInfo(node_b3, model()); + const auto* node_c3 = + model()->AddURL(model()->bookmark_bar_node(), 6, + base::ASCIIToUTF16("C3.com"), GURL("https://c3.com/")); + AddBraveMetaInfo(node_c3, model()); + + std::string a3_order; + node_a3->GetMetaInfo("order", &a3_order); + EXPECT_TRUE(!a3_order.empty()); + + std::string a3_object_id; + node_a3->GetMetaInfo("object_id", &a3_object_id); + EXPECT_TRUE(!a3_object_id.empty()); + + // Emulating nodes a3, b3, and c3 have the same order + const_cast(node_b3)->SetMetaInfo("order", a3_order); + const_cast(node_c3)->SetMetaInfo("order", a3_order); + + // Expecting sorting of same order bookmarks by object_id + // object_id is 16 comma and spaces separated values of 16 uint8 + // Will assign these object ids to make RepositionRespectOrder do sorting: + // C3 A3 B3 + // "..." < 1,2,3 < "@@@" + ASSERT_TRUE("..." < a3_object_id && a3_object_id < "@@@"); + const_cast(node_b3)->SetMetaInfo("object_id", "@@@"); + const_cast(node_c3)->SetMetaInfo("object_id", "..."); + + // 0 1 2 3 4 5 6 + // A1 A2 B1 B2 A3(1,2,3) B3(@@@) C3(...) + auto title_at_4 = model()->bookmark_bar_node()->GetChild(4)->GetTitle(); + EXPECT_EQ(title_at_4, base::ASCIIToUTF16("A3.com")); + auto title_at_5 = model()->bookmark_bar_node()->GetChild(5)->GetTitle(); + EXPECT_EQ(title_at_5, base::ASCIIToUTF16("B3.com")); + auto title_at_6 = model()->bookmark_bar_node()->GetChild(6)->GetTitle(); + EXPECT_EQ(title_at_6, base::ASCIIToUTF16("C3.com")); + + RepositionRespectOrder(model(), node_b3); + // 0 1 2 3 4 5 6 + // A1 A2 B1 B2 A3(1,2,3) B3(@@@) C3(...) + // node B3 hadn't moved because it reached itself + title_at_4 = model()->bookmark_bar_node()->GetChild(4)->GetTitle(); + EXPECT_EQ(title_at_4, base::ASCIIToUTF16("A3.com")); + title_at_5 = model()->bookmark_bar_node()->GetChild(5)->GetTitle(); + EXPECT_EQ(title_at_5, base::ASCIIToUTF16("B3.com")); + title_at_6 = model()->bookmark_bar_node()->GetChild(6)->GetTitle(); + EXPECT_EQ(title_at_6, base::ASCIIToUTF16("C3.com")); + + RepositionRespectOrder(model(), node_c3); + // 0 1 2 3 4 5 6 + // A1 A2 B1 B2 C3(...) A3(1,2,3) B3(@@@) + // node C3 moved to the correct position, so B3 is on the right place now + + title_at_4 = model()->bookmark_bar_node()->GetChild(4)->GetTitle(); + EXPECT_EQ(title_at_4, base::ASCIIToUTF16("C3.com")); + title_at_5 = model()->bookmark_bar_node()->GetChild(5)->GetTitle(); + EXPECT_EQ(title_at_5, base::ASCIIToUTF16("A3.com")); + title_at_6 = model()->bookmark_bar_node()->GetChild(6)->GetTitle(); + EXPECT_EQ(title_at_6, base::ASCIIToUTF16("B3.com")); +} + +} // namespace brave_sync diff --git a/components/brave_sync/test_util.cc b/components/brave_sync/test_util.cc index b7858a045a7e..8d64a654654a 100644 --- a/components/brave_sync/test_util.cc +++ b/components/brave_sync/test_util.cc @@ -1,16 +1,18 @@ -/* 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 2019 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/test_util.h" +#include + #include "base/files/file_util.h" #include "base/strings/utf_string_conversions.h" -#include "brave/components/brave_sync/brave_sync_service_factory.h" -#include "brave/components/brave_sync/client/bookmark_node.h" #include "brave/components/brave_sync/tools.h" #include "brave/components/brave_sync/values_conv.h" #include "chrome/browser/prefs/browser_prefs.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/bookmarks/browser/bookmark_model.h" @@ -18,21 +20,6 @@ #include "components/sync_preferences/pref_service_mock_factory.h" #include "components/sync_preferences/testing_pref_service_syncable.h" -namespace { - -using namespace bookmarks; - -void AddPermanentNode(BookmarkPermanentNodeList* extra_nodes, int64_t id, - const std::string& title) { - auto node = std::make_unique(id); - node->set_type(bookmarks::BookmarkNode::FOLDER); - node->set_visible(false); - node->SetTitle(base::UTF8ToUTF16(title)); - extra_nodes->push_back(std::move(node)); -} - -} // namespace - namespace brave_sync { MockBraveSyncClient::MockBraveSyncClient() {} @@ -40,7 +27,7 @@ MockBraveSyncClient::MockBraveSyncClient() {} MockBraveSyncClient::~MockBraveSyncClient() {} std::unique_ptr CreateBraveSyncProfile(const base::FilePath& path) { - BraveSyncServiceFactory::GetInstance(); + ProfileSyncServiceFactory::GetInstance(); sync_preferences::PrefServiceMockFactory factory; auto registry = base::MakeRefCounted(); @@ -56,35 +43,29 @@ std::unique_ptr CreateBraveSyncProfile(const base::FilePath& path) { std::unique_ptr BuildFakeBookmarkModelForTests( content::BrowserContext* context) { + using bookmarks::BookmarkModel; + using bookmarks::TestBookmarkClient; // Don't need context, unless we have more than one profile - using namespace bookmarks; std::unique_ptr client(new TestBookmarkClient()); - BookmarkPermanentNodeList extra_nodes; - - // These hard-coded titles cannot be changed - AddPermanentNode(&extra_nodes, 0xDE1E7ED40DE, "Deleted Bookmarks"); - AddPermanentNode(&extra_nodes, 0x9E7D17640DE, "Pending Bookmarks"); - - client->SetExtraNodesToLoad(std::move(extra_nodes)); std::unique_ptr model( TestBookmarkClient::CreateModelWithClient(std::move(client))); return model; } -SyncRecordPtr SimpleBookmarkSyncRecord( - const int action, - const std::string& object_id, - const std::string& location, - const std::string& title, - const std::string& order, - const std::string& parent_object_id) { +SyncRecordPtr SimpleBookmarkSyncRecord(const int action, + const std::string& object_id, + const std::string& location, + const std::string& title, + const std::string& order, + const std::string& parent_object_id, + const std::string& device_id) { auto record = std::make_unique(); record->action = ConvertEnum(action, brave_sync::jslib::SyncRecord::Action::A_MIN, brave_sync::jslib::SyncRecord::Action::A_MAX, brave_sync::jslib::SyncRecord::Action::A_INVALID); - record->deviceId = "3"; + record->deviceId = device_id; record->objectId = object_id.empty() ? tools::GenerateObjectId() : object_id; record->objectData = "bookmark"; @@ -161,4 +142,4 @@ SyncRecordPtr SimpleDeviceRecord( return record; } -} // namespace +} // namespace brave_sync diff --git a/components/brave_sync/test_util.h b/components/brave_sync/test_util.h index e63894af871e..fa60e3bfa5bf 100644 --- a/components/brave_sync/test_util.h +++ b/components/brave_sync/test_util.h @@ -1,11 +1,14 @@ -/* 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 2019 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/. */ #ifndef BRAVE_COMPONENTS_BRAVE_SYNC_TEST_UTIL_H_ #define BRAVE_COMPONENTS_BRAVE_SYNC_TEST_UTIL_H_ #include +#include +#include #include "base/files/file_path.h" #include "brave/components/brave_sync/client/brave_sync_client.h" @@ -41,8 +44,9 @@ class MockBraveSyncClient : public BraveSyncClient { MOCK_METHOD0(SendFetchSyncDevices, void()); MOCK_METHOD2(SendResolveSyncRecords, void(const std::string& category_name, std::unique_ptr list)); - MOCK_METHOD2(SendSyncRecords, void (const std::string& category_name, - const RecordsList& records)); + MOCK_METHOD2(SendSyncRecords, + void(const std::string& category_name, + const RecordsList& records)); MOCK_METHOD0(SendDeleteSyncUser, void()); MOCK_METHOD1(SendDeleteSyncCategory, void(const std::string& category_name)); MOCK_METHOD2(SendGetBookmarksBaseOrder, void(const std::string& device_id, @@ -59,13 +63,13 @@ std::unique_ptr CreateBraveSyncProfile(const base::FilePath& path); std::unique_ptr BuildFakeBookmarkModelForTests( content::BrowserContext* context); -SyncRecordPtr SimpleBookmarkSyncRecord( - const int action, - const std::string& object_id, - const std::string& location, - const std::string& title, - const std::string& order, - const std::string& parent_object_id); +SyncRecordPtr SimpleBookmarkSyncRecord(const int action, + const std::string& object_id, + const std::string& location, + const std::string& title, + const std::string& order, + const std::string& parent_object_id, + const std::string& device_id = "3"); SyncRecordPtr SimpleFolderSyncRecord( const int action, diff --git a/patches/chrome-browser-prefs-browser_prefs.cc.patch b/patches/chrome-browser-prefs-browser_prefs.cc.patch index 976faa7adf74..57f85203cf1a 100644 --- a/patches/chrome-browser-prefs-browser_prefs.cc.patch +++ b/patches/chrome-browser-prefs-browser_prefs.cc.patch @@ -1,5 +1,5 @@ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc -index 50312cdb0324e3dad18c77c96e5e609bfb259541..ed0ab71e9e08494abb5016bcb4e1fce6f852ea24 100644 +index 50312cdb0324e3dad18c77c96e5e609bfb259541..2298f9b60d2718d82e721dc8483b114931a30d0d 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -658,6 +658,7 @@ void RegisterLocalState(PrefRegistrySimple* registry) { @@ -10,3 +10,11 @@ index 50312cdb0324e3dad18c77c96e5e609bfb259541..ed0ab71e9e08494abb5016bcb4e1fce6 } // Register prefs applicable to all profiles. +@@ -908,6 +909,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry, + #endif + + RegisterProfilePrefsForMigration(registry); ++ brave::RegisterProfilePrefs(registry); + } + + void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { diff --git a/patches/chrome-browser-profiles-profile_impl.cc.patch b/patches/chrome-browser-profiles-profile_impl.cc.patch index e04ed4a31c75..ad4ce212270f 100644 --- a/patches/chrome-browser-profiles-profile_impl.cc.patch +++ b/patches/chrome-browser-profiles-profile_impl.cc.patch @@ -1,5 +1,5 @@ diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc -index 71619ca3d5271b0f813110dce0e5570b6eebdda7..a9c1f8ec99aafa581c7fc8261e470261323c6492 100644 +index 71619ca3d5271b0f813110dce0e5570b6eebdda7..97003f2bc6f1141ae49dc2a2ac58e5f861fd0615 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -34,6 +34,7 @@ @@ -10,13 +10,3 @@ index 71619ca3d5271b0f813110dce0e5570b6eebdda7..a9c1f8ec99aafa581c7fc8261e470261 #include "build/build_config.h" #include "chrome/browser/background/background_contents_service_factory.h" #include "chrome/browser/background_fetch/background_fetch_delegate_factory.h" -@@ -508,6 +509,9 @@ ProfileImpl::ProfileImpl( - LoadPrefsForNormalStartup(async_prefs); - #endif - -+// Done here instead of browser_prefs.cc so it can override default prefs -+brave::RegisterProfilePrefs(pref_registry_.get()); -+ - content::BrowserContext::Initialize(this, path_); - - // Register on BrowserContext. diff --git a/patches/chrome-browser-resources-bookmarks-api_listener.js.patch b/patches/chrome-browser-resources-bookmarks-api_listener.js.patch new file mode 100644 index 000000000000..d80d1c1cb827 --- /dev/null +++ b/patches/chrome-browser-resources-bookmarks-api_listener.js.patch @@ -0,0 +1,20 @@ +diff --git a/chrome/browser/resources/bookmarks/api_listener.js b/chrome/browser/resources/bookmarks/api_listener.js +index 7bc20ec28e9faebc14dba26c277ea07db0940ed7..b1bafab103435383bbfa27338b8064aae38c1c44 100644 +--- a/chrome/browser/resources/bookmarks/api_listener.js ++++ b/chrome/browser/resources/bookmarks/api_listener.js +@@ -135,6 +135,7 @@ cr.define('bookmarks.ApiListener', function() { + */ + function onImportBegan() { + chrome.bookmarks.onCreated.removeListener(onBookmarkCreated); ++ chrome.bookmarks.onMoved.removeListener(onBookmarkMoved); + } + + function onImportEnded() { +@@ -143,6 +144,7 @@ cr.define('bookmarks.ApiListener', function() { + bookmarks.util.normalizeNodes(results[0]))); + }); + chrome.bookmarks.onCreated.addListener(onBookmarkCreated); ++ chrome.bookmarks.onMoved.addListener(onBookmarkMoved); + } + + /** diff --git a/patches/chrome-browser-sync-profile_sync_service_factory.cc.patch b/patches/chrome-browser-sync-profile_sync_service_factory.cc.patch new file mode 100644 index 000000000000..54447ea55c95 --- /dev/null +++ b/patches/chrome-browser-sync-profile_sync_service_factory.cc.patch @@ -0,0 +1,13 @@ +diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc +index 5059e39e28bb076eb26cd5fda1f61223591023b7..ef2ecbb8b653663fdf5dbd76adca2a87543fd6e7 100644 +--- a/chrome/browser/sync/profile_sync_service_factory.cc ++++ b/chrome/browser/sync/profile_sync_service_factory.cc +@@ -264,7 +264,7 @@ KeyedService* ProfileSyncServiceFactory::BuildServiceInstanceFor( + } + + auto pss = +- std::make_unique(std::move(init_params)); ++ BraveBuildServiceInstanceFor(profile, std::move(init_params)); + pss->Initialize(); + + // Hook PSS into PersonalDataManager (a circular dependency). diff --git a/patches/chrome-browser-ui-autofill-payments-save_card_bubble_controller_impl.cc.patch b/patches/chrome-browser-ui-autofill-payments-save_card_bubble_controller_impl.cc.patch index 1a40958d1b32..681d3033a713 100644 --- a/patches/chrome-browser-ui-autofill-payments-save_card_bubble_controller_impl.cc.patch +++ b/patches/chrome-browser-ui-autofill-payments-save_card_bubble_controller_impl.cc.patch @@ -1,12 +1,12 @@ diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc -index e576d1a0a1f331679c586ef63a17c38063501611..c308f33b68f0f011523798cde65f36f668b187a4 100644 +index e576d1a0a1f331679c586ef63a17c38063501611..efc02bac3777f2050c2399987c5522422740fa3d 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc -@@ -437,6 +437,7 @@ bool SaveCardBubbleControllerImpl::ShouldRequestExpirationDateFromUser() const { - } +@@ -442,6 +442,7 @@ bool SaveCardBubbleControllerImpl::ShouldShowSignInPromo() const { - bool SaveCardBubbleControllerImpl::ShouldShowSignInPromo() const { -+ BRAVE_SHOULD_SHOW_SIGNIN_PROMO_SHORT_CIRCUIT_TO_FALSE; - if (is_upload_save_) - return false; + const syncer::SyncService* sync_service = + ProfileSyncServiceFactory::GetForProfile(GetProfile()); ++ CHECK_SYNC_POLICY + return !sync_service || + sync_service->HasDisableReason( diff --git a/patches/components-sync-base-BUILD.gn.patch b/patches/components-sync-base-BUILD.gn.patch new file mode 100644 index 000000000000..2677aa8e4e2d --- /dev/null +++ b/patches/components-sync-base-BUILD.gn.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/base/BUILD.gn b/components/sync/base/BUILD.gn +index c36114532adaea827b566f99ce180421d8fcf623..cf243553011cf7a3564f46abac053e5d53e3de25 100644 +--- a/components/sync/base/BUILD.gn ++++ b/components/sync/base/BUILD.gn +@@ -77,6 +77,7 @@ jumbo_static_library("base") { + ] + deps = [ + "//base:i18n", ++ "//brave/components/brave_sync:public", + "//components/os_crypt", + "//components/pref_registry", + "//components/prefs", diff --git a/patches/components-sync-driver-glue-sync_engine_backend.cc.patch b/patches/components-sync-driver-glue-sync_engine_backend.cc.patch new file mode 100644 index 000000000000..8e01a0ce4307 --- /dev/null +++ b/patches/components-sync-driver-glue-sync_engine_backend.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/driver/glue/sync_engine_backend.cc b/components/sync/driver/glue/sync_engine_backend.cc +index f6cdade4a559d1f1e329bc1e4329680407220926..291c26eab481308e05a8eb4f32bd71c2b4d62f0b 100644 +--- a/components/sync/driver/glue/sync_engine_backend.cc ++++ b/components/sync/driver/glue/sync_engine_backend.cc +@@ -342,6 +342,7 @@ void SyncEngineBackend::DoInitialize(SyncEngine::InitParams params) { + args.cache_guid = params.cache_guid; + args.birthday = params.birthday; + args.bag_of_chips = params.bag_of_chips; ++ BRAVE_SYNC_ENGINE_BACKEND_DO_INITIALIZE + sync_manager_->Init(&args); + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + this, "SyncDirectory", base::ThreadTaskRunnerHandle::Get()); diff --git a/patches/components-sync-driver-glue-sync_engine_impl.h.patch b/patches/components-sync-driver-glue-sync_engine_impl.h.patch new file mode 100644 index 000000000000..f6d7fd2a3c6e --- /dev/null +++ b/patches/components-sync-driver-glue-sync_engine_impl.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/driver/glue/sync_engine_impl.h b/components/sync/driver/glue/sync_engine_impl.h +index fa18e8241e3b7c3ea4e95b764fea19080e626d0d..f8d2e5a704d7f970ffeee0cd228607056cb6a868 100644 +--- a/components/sync/driver/glue/sync_engine_impl.h ++++ b/components/sync/driver/glue/sync_engine_impl.h +@@ -218,6 +218,7 @@ class SyncEngineImpl : public SyncEngine, public InvalidationHandler { + + base::WeakPtrFactory weak_ptr_factory_; + ++ BRAVE_SYNC_ENGINE_IMPL_H + DISALLOW_COPY_AND_ASSIGN(SyncEngineImpl); + }; + diff --git a/patches/components-sync-driver-profile_sync_service.cc.patch b/patches/components-sync-driver-profile_sync_service.cc.patch new file mode 100644 index 000000000000..595b6a9f5f60 --- /dev/null +++ b/patches/components-sync-driver-profile_sync_service.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc +index ead807e7c2810a4e32d738004a3911c1ac954b0d..ec73a7c8c4ad24ea72e734f7f98d664807cf9685 100644 +--- a/components/sync/driver/profile_sync_service.cc ++++ b/components/sync/driver/profile_sync_service.cc +@@ -463,6 +463,7 @@ void ProfileSyncService::StartUpSlowEngineComponents() { + params.sync_user_agent = MakeUserAgentForSync(channel_); + params.http_factory_getter = MakeHttpPostProviderFactoryGetter(); + params.authenticated_account_id = GetAuthenticatedAccountInfo().account_id; ++ BRAVE_PROFILE_SYNC_SERVICE_START_UP_SLOW_ENGINE_COMPONENTS + DCHECK(!params.authenticated_account_id.empty() || IsLocalSyncEnabled()); + if (!base::FeatureList::IsEnabled(switches::kSyncE2ELatencyMeasurement)) { + invalidation::InvalidationService* invalidator = diff --git a/patches/components-sync-driver-profile_sync_service.h.patch b/patches/components-sync-driver-profile_sync_service.h.patch new file mode 100644 index 000000000000..915afe8eede5 --- /dev/null +++ b/patches/components-sync-driver-profile_sync_service.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/driver/profile_sync_service.h b/components/sync/driver/profile_sync_service.h +index eb37180610ac149898aa326dfc391e4dccb4e35c..dcba3d59c7ee0d60768dcc3e684109b2f878beeb 100644 +--- a/components/sync/driver/profile_sync_service.h ++++ b/components/sync/driver/profile_sync_service.h +@@ -500,6 +500,7 @@ class ProfileSyncService : public SyncService, + + base::WeakPtrFactory weak_factory_; + ++ BRAVE_PROFILE_SYNC_SERVICE_H + DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); + }; + diff --git a/patches/components-sync-engine-sync_engine.h.patch b/patches/components-sync-engine-sync_engine.h.patch new file mode 100644 index 000000000000..ce25e1f28ec3 --- /dev/null +++ b/patches/components-sync-engine-sync_engine.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine/sync_engine.h b/components/sync/engine/sync_engine.h +index 8d53e56f05b9d788d863593c03c8321b0683ea3c..775309aa9b352ebe290141860c3324c5325c4bc3 100644 +--- a/components/sync/engine/sync_engine.h ++++ b/components/sync/engine/sync_engine.h +@@ -82,6 +82,7 @@ class SyncEngine : public ModelTypeConfigurer { + + // Define the polling interval. Must not be zero. + base::TimeDelta poll_interval; ++ BRAVE_SYNC_ENGINE_INIT_PARAMS_H + + private: + DISALLOW_COPY_AND_ASSIGN(InitParams); diff --git a/patches/components-sync-engine-sync_manager.h.patch b/patches/components-sync-engine-sync_manager.h.patch new file mode 100644 index 000000000000..db971e4224d4 --- /dev/null +++ b/patches/components-sync-engine-sync_manager.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine/sync_manager.h b/components/sync/engine/sync_manager.h +index 9dbc229893be5e6c60a15f7f9ccd5de6fc918f15..cf9e8c2f193f581de17c7b546856ab588e588907 100644 +--- a/components/sync/engine/sync_manager.h ++++ b/components/sync/engine/sync_manager.h +@@ -251,6 +251,7 @@ class SyncManager { + std::string cache_guid; + std::string birthday; + std::string bag_of_chips; ++ BRAVE_SYNC_MANAGER_INIT_ARGS_H + }; + + // The state of sync the feature. If the user turned on sync explicitly, it diff --git a/patches/components-sync-engine_impl-commit.cc.patch b/patches/components-sync-engine_impl-commit.cc.patch new file mode 100644 index 000000000000..92e639bad9fa --- /dev/null +++ b/patches/components-sync-engine_impl-commit.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/commit.cc b/components/sync/engine_impl/commit.cc +index 312f59cb0e7126d2c7d3059f3eef8819f993c523..7db6e6d7bea2c14847425d44fc5f3a9bfcd372d5 100644 +--- a/components/sync/engine_impl/commit.cc ++++ b/components/sync/engine_impl/commit.cc +@@ -133,6 +133,7 @@ SyncerError Commit::PostAndProcessResponse( + sync_pb::ClientToServerResponse response; + const SyncerError post_result = SyncerProtoUtil::PostClientToServerMessage( + message_, &response, cycle, nullptr); ++ BRAVE_COMMIT_POST_AND_PROCESS_RESPONSE + TRACE_EVENT_END0("sync", "PostCommit"); + + // TODO(rlarocque): Use result that includes errors captured later? diff --git a/patches/components-sync-engine_impl-cycle-sync_cycle.h.patch b/patches/components-sync-engine_impl-cycle-sync_cycle.h.patch new file mode 100644 index 000000000000..19818194d25e --- /dev/null +++ b/patches/components-sync-engine_impl-cycle-sync_cycle.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/cycle/sync_cycle.h b/components/sync/engine_impl/cycle/sync_cycle.h +index 0971b6014231f8046eca9202840acc6167960057..6f7adf18b33be49f18469026838cbd9ad64bb8c5 100644 +--- a/components/sync/engine_impl/cycle/sync_cycle.h ++++ b/components/sync/engine_impl/cycle/sync_cycle.h +@@ -79,6 +79,7 @@ class SyncCycle { + + // Called when server requests a migration. + virtual void OnReceivedMigrationRequest(ModelTypeSet types) = 0; ++ BRAVE_SYNC_CYCLE_DELEGATE_H + + protected: + virtual ~Delegate() {} diff --git a/patches/components-sync-engine_impl-get_updates_processor.cc.patch b/patches/components-sync-engine_impl-get_updates_processor.cc.patch new file mode 100644 index 000000000000..772c3bee380d --- /dev/null +++ b/patches/components-sync-engine_impl-get_updates_processor.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/get_updates_processor.cc b/components/sync/engine_impl/get_updates_processor.cc +index faeff075cf940e8c1db7941f4c3dca27bf63f580..af6143ed5625e060ca17e5ebf93fbbd4a85061d2 100644 +--- a/components/sync/engine_impl/get_updates_processor.cc ++++ b/components/sync/engine_impl/get_updates_processor.cc +@@ -225,6 +225,7 @@ SyncerError GetUpdatesProcessor::ExecuteDownloadUpdates( + + SyncerError result = SyncerProtoUtil::PostClientToServerMessage( + *msg, &update_response, cycle, &partial_failure_data_types); ++ result = ApplyBraveRecords(&update_response, request_types, std::move(brave_records_)); + + DVLOG(2) << SyncerProtoUtil::ClientToServerResponseDebugString( + update_response); diff --git a/patches/components-sync-engine_impl-get_updates_processor.h.patch b/patches/components-sync-engine_impl-get_updates_processor.h.patch new file mode 100644 index 000000000000..2382643845b6 --- /dev/null +++ b/patches/components-sync-engine_impl-get_updates_processor.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/get_updates_processor.h b/components/sync/engine_impl/get_updates_processor.h +index c5560ec8113670c57f80245199031732f5795f23..f883a3aa1251dab8cd2ae07c467cbe42a1ebd089 100644 +--- a/components/sync/engine_impl/get_updates_processor.h ++++ b/components/sync/engine_impl/get_updates_processor.h +@@ -96,6 +96,7 @@ class GetUpdatesProcessor { + + const GetUpdatesDelegate& delegate_; + ++ BRAVE_GET_UPDATES_PROCESSOR_H + DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessor); + }; + diff --git a/patches/components-sync-engine_impl-sync_manager_impl.cc.patch b/patches/components-sync-engine_impl-sync_manager_impl.cc.patch new file mode 100644 index 000000000000..ce43c0eb0f26 --- /dev/null +++ b/patches/components-sync-engine_impl-sync_manager_impl.cc.patch @@ -0,0 +1,15 @@ +diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc +index 4d43b0de7d7376d13b587b2d5c4d7beac38720c8..114689f853e0b4938ebda84d1dba52cdbac35cb1 100644 +--- a/components/sync/engine_impl/sync_manager_impl.cc ++++ b/components/sync/engine_impl/sync_manager_impl.cc +@@ -410,8 +410,9 @@ void SyncManagerImpl::Init(InitArgs* args) { + args->poll_interval); + scheduler_ = args->engine_components_factory->BuildScheduler( + name_, cycle_context_.get(), args->cancelation_signal, +- args->enable_local_sync_backend); ++ true); + ++ BRAVE_SYNC_MANAGER_IMPL_INIT + scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time()); + + initialized_ = true; diff --git a/patches/components-sync-engine_impl-sync_scheduler_impl.cc.patch b/patches/components-sync-engine_impl-sync_scheduler_impl.cc.patch new file mode 100644 index 000000000000..3f5b8d0e4d46 --- /dev/null +++ b/patches/components-sync-engine_impl-sync_scheduler_impl.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/sync_scheduler_impl.cc b/components/sync/engine_impl/sync_scheduler_impl.cc +index 217652eec756c9e4ff4bf7bd74a9cd481672ed1b..7e153a22dd363213f1a0091e295ec9f2d5120cea 100644 +--- a/components/sync/engine_impl/sync_scheduler_impl.cc ++++ b/components/sync/engine_impl/sync_scheduler_impl.cc +@@ -660,6 +660,7 @@ void SyncSchedulerImpl::TryCanaryJob() { + } + + void SyncSchedulerImpl::TrySyncCycleJob() { ++ BRAVE_SYNC_SCHEDULER_IMPL_TRY_SYNC_CYCLE_JOB + // Post call to TrySyncCycleJobImpl on current sequence. Later request for + // access token will be here. + base::SequencedTaskRunnerHandle::Get()->PostTask( diff --git a/patches/components-sync-engine_impl-sync_scheduler_impl.h.patch b/patches/components-sync-engine_impl-sync_scheduler_impl.h.patch new file mode 100644 index 000000000000..a86ef8eedd44 --- /dev/null +++ b/patches/components-sync-engine_impl-sync_scheduler_impl.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/sync_scheduler_impl.h b/components/sync/engine_impl/sync_scheduler_impl.h +index 4bab39098da187109f291f1c0ab03fd0cc34d326..8cca9aedd53f4a6f636adb168bad115ff68ec5af 100644 +--- a/components/sync/engine_impl/sync_scheduler_impl.h ++++ b/components/sync/engine_impl/sync_scheduler_impl.h +@@ -87,6 +87,7 @@ class SyncSchedulerImpl : public SyncScheduler { + // tests. + void ForceShortNudgeDelayForTest(); + ++ BRAVE_SYNC_SCHEDULER_IMPL_H_ + private: + enum JobPriority { + // Non-canary jobs respect exponential backoff. diff --git a/patches/components-sync-engine_impl-syncer.cc.patch b/patches/components-sync-engine_impl-syncer.cc.patch new file mode 100644 index 000000000000..2d8b96f9e20f --- /dev/null +++ b/patches/components-sync-engine_impl-syncer.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/syncer.cc b/components/sync/engine_impl/syncer.cc +index ca2de93b0400bc718446f6aea2930000166df515..5a65337357aedd08edef53f7d14ca5f6a2c1802f 100644 +--- a/components/sync/engine_impl/syncer.cc ++++ b/components/sync/engine_impl/syncer.cc +@@ -111,6 +111,7 @@ bool Syncer::DownloadAndApplyUpdates(ModelTypeSet* request_types, + Difference(*request_types, requested_commit_only_types); + GetUpdatesProcessor get_updates_processor( + cycle->context()->model_type_registry()->update_handler_map(), delegate); ++ get_updates_processor.AddBraveRecords(std::move(brave_records_)); + SyncerError download_result; + do { + download_result = diff --git a/patches/components-sync-engine_impl-syncer.h.patch b/patches/components-sync-engine_impl-syncer.h.patch new file mode 100644 index 000000000000..a11771dfb757 --- /dev/null +++ b/patches/components-sync-engine_impl-syncer.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/engine_impl/syncer.h b/components/sync/engine_impl/syncer.h +index 23b389eada81c850c3a8856678d046e599a060da..30ce667ae1e00e51bf4f227084da8f4ca30f8dc2 100644 +--- a/components/sync/engine_impl/syncer.h ++++ b/components/sync/engine_impl/syncer.h +@@ -94,6 +94,7 @@ class Syncer { + // Whether the syncer is in the middle of a sync attempt. + bool is_syncing_; + ++ BRAVE_SYNCER_H + DISALLOW_COPY_AND_ASSIGN(Syncer); + }; + diff --git a/patches/components-sync-engine_impl-syncer_proto_util.cc.patch b/patches/components-sync-engine_impl-syncer_proto_util.cc.patch new file mode 100644 index 000000000000..243bcaa0ef31 --- /dev/null +++ b/patches/components-sync-engine_impl-syncer_proto_util.cc.patch @@ -0,0 +1,20 @@ +diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc +index 791e269c8b9933093826991e7a73bb75878f8b1b..e353365024f0338493aff29c48b9140f8f269982 100644 +--- a/components/sync/engine_impl/syncer_proto_util.cc ++++ b/components/sync/engine_impl/syncer_proto_util.cc +@@ -394,6 +394,7 @@ base::TimeDelta SyncerProtoUtil::GetThrottleDelay( + void SyncerProtoUtil::AddRequiredFieldsToClientToServerMessage( + const SyncCycle* cycle, + sync_pb::ClientToServerMessage* msg) { ++ return; + DCHECK(msg); + SetProtocolVersion(msg); + const std::string birthday = cycle->context()->birthday(); +@@ -413,6 +414,7 @@ SyncerError SyncerProtoUtil::PostClientToServerMessage( + ClientToServerResponse* response, + SyncCycle* cycle, + ModelTypeSet* partial_failure_data_types) { ++ return SyncerError(SyncerError::SYNCER_OK); + DCHECK(response); + DCHECK(msg.has_protocol_version()); + DCHECK(msg.has_store_birthday() || !IsBirthdayRequired(msg)); diff --git a/patches/components-sync-syncable-write_transaction.cc.patch b/patches/components-sync-syncable-write_transaction.cc.patch new file mode 100644 index 000000000000..4b25c62fbfe2 --- /dev/null +++ b/patches/components-sync-syncable-write_transaction.cc.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/syncable/write_transaction.cc b/components/sync/syncable/write_transaction.cc +index 00b248a93830bbafae831d46d1089a0844c57805..f2dfcd72d90ec73d84180fd91a8db6c0270fb033 100644 +--- a/components/sync/syncable/write_transaction.cc ++++ b/components/sync/syncable/write_transaction.cc +@@ -28,6 +28,7 @@ WriteTransaction::WriteTransaction(const base::Location& from_here, + } + + WriteTransaction::~WriteTransaction() { ++ BRAVE_WRITE_TRANSACTION + delete transaction_; + } + diff --git a/patches/components-sync-syncable-write_transaction.h.patch b/patches/components-sync-syncable-write_transaction.h.patch new file mode 100644 index 000000000000..fd11ad582ffc --- /dev/null +++ b/patches/components-sync-syncable-write_transaction.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync/syncable/write_transaction.h b/components/sync/syncable/write_transaction.h +index 3d0a353ac09b1dcbfab0d5afc3345d78eb4ee8bd..b53e56bc0c43a43da32bd736eb86368e3bebec87 100644 +--- a/components/sync/syncable/write_transaction.h ++++ b/components/sync/syncable/write_transaction.h +@@ -56,6 +56,7 @@ class WriteTransaction : public BaseTransaction { + SyncChangeProcessor::ContextRefreshStatus refresh_status, + const std::string& context); + ++ BRAVE_WRITE_TRANSACTION_H_ + protected: + WriteTransaction() {} + diff --git a/patches/components-sync_bookmarks-bookmark_change_processor.cc.patch b/patches/components-sync_bookmarks-bookmark_change_processor.cc.patch new file mode 100644 index 000000000000..134d6d28b265 --- /dev/null +++ b/patches/components-sync_bookmarks-bookmark_change_processor.cc.patch @@ -0,0 +1,60 @@ +diff --git a/components/sync_bookmarks/bookmark_change_processor.cc b/components/sync_bookmarks/bookmark_change_processor.cc +index 35a73a07bbcdd8aeba13acf37c6754aadb039768..ce1af3e95e3745bf3cb06ecd5a94ed29b3ec4355 100644 +--- a/components/sync_bookmarks/bookmark_change_processor.cc ++++ b/components/sync_bookmarks/bookmark_change_processor.cc +@@ -87,6 +87,7 @@ void BookmarkChangeProcessor::UpdateSyncNodeProperties( + bookmark_specifics.set_creation_time_us(src->date_added().ToInternalValue()); + dst->SetBookmarkSpecifics(bookmark_specifics); + SetSyncNodeFavicon(src, model, dst); ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_UPDATE_SYNC_NODE_PROPERTIES + SetSyncNodeMetaInfo(src, dst); + } + +@@ -383,7 +384,6 @@ int64_t BookmarkChangeProcessor::UpdateSyncNode( + + void BookmarkChangeProcessor::BookmarkMetaInfoChanged( + BookmarkModel* model, const BookmarkNode* node) { +- BookmarkNodeChanged(model, node); + } + + void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model, +@@ -415,6 +415,7 @@ void BookmarkChangeProcessor::BookmarkNodeMoved(BookmarkModel* model, + error_handler()->OnUnrecoverableError(error); + return; + } ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_BOOKMARK_NODE_MOVED + + if (!PlaceSyncNode(MOVE, new_parent, new_index, &trans, &sync_node, + model_associator_)) { +@@ -458,6 +459,7 @@ void BookmarkChangeProcessor::BookmarkNodeFaviconChanged( + return; + } + ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_BOOKMARK_NODE_FAVICON_CHANGED + CreateOrUpdateSyncNode(node); + } + +@@ -490,6 +492,7 @@ void BookmarkChangeProcessor::BookmarkNodeChildrenReordered( + DCHECK_EQ(sync_child.GetParentId(), + model_associator_->GetSyncIdFromChromeId(node->id())); + ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_CHILDREN_REORDERED + if (!PlaceSyncNode(MOVE, node, i, &trans, &sync_child, + model_associator_)) { + syncer::SyncError error(FROM_HERE, +@@ -718,6 +721,7 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel( + << src.GetBookmarkSpecifics().url(); + continue; + } ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_APPLY_CHANGES_FROM_SYNC_MODEL_1 + model_associator_->Associate(dst, src); + } + +@@ -730,6 +734,7 @@ void BookmarkChangeProcessor::ApplyChangesFromSyncModel( + // sync order, left to right, moving them into their proper positions. + for (auto it = to_reposition.begin(); it != to_reposition.end(); ++it) { + const BookmarkNode* parent = it->second->parent(); ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_APPLY_CHANGES_FROM_SYNC_MODEL_2 + model->Move(it->second, parent, it->first); + } + diff --git a/patches/components-sync_bookmarks-bookmark_change_processor.h.patch b/patches/components-sync_bookmarks-bookmark_change_processor.h.patch new file mode 100644 index 000000000000..b28c03036cc2 --- /dev/null +++ b/patches/components-sync_bookmarks-bookmark_change_processor.h.patch @@ -0,0 +1,12 @@ +diff --git a/components/sync_bookmarks/bookmark_change_processor.h b/components/sync_bookmarks/bookmark_change_processor.h +index e11a2ddf641edc7098c06433fd22d86467e2aabf..d29059927ef563fb6e0a365da740d50ba8360bfd 100644 +--- a/components/sync_bookmarks/bookmark_change_processor.h ++++ b/components/sync_bookmarks/bookmark_change_processor.h +@@ -172,6 +172,7 @@ class BookmarkChangeProcessor : public bookmarks::BookmarkModelObserver, + bookmarks::BookmarkModel* model, + const std::vector& nodes); + ++ BRAVE_BOOKMARK_CHANGE_PROCESSOR_H_ + protected: + void StartImpl() override; + diff --git a/patches/components-sync_device_info-device_info_sync_bridge.cc.patch b/patches/components-sync_device_info-device_info_sync_bridge.cc.patch new file mode 100644 index 000000000000..50efba228a9a --- /dev/null +++ b/patches/components-sync_device_info-device_info_sync_bridge.cc.patch @@ -0,0 +1,13 @@ +diff --git a/components/sync_device_info/device_info_sync_bridge.cc b/components/sync_device_info/device_info_sync_bridge.cc +index a809fd09ea04d28b7293d1554f29f0c83dd648a3..c0066b8ab45e9956a7d094d9bd9ddd45d5e674c3 100644 +--- a/components/sync_device_info/device_info_sync_bridge.cc ++++ b/components/sync_device_info/device_info_sync_bridge.cc +@@ -254,7 +254,7 @@ std::string DeviceInfoSyncBridge::GetStorageKey(const EntityData& entity_data) { + void DeviceInfoSyncBridge::ApplyStopSyncChanges( + std::unique_ptr delete_metadata_change_list) { + if (!delete_metadata_change_list) { +- return; ++ // return; + } + + // Sync is being disabled, so the local DeviceInfo is no longer valid and diff --git a/test/BUILD.gn b/test/BUILD.gn index e11dbd2517ec..0e84cc855759 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -3,6 +3,7 @@ import("//brave/browser/tor/buildflags/buildflags.gni") import("//brave/browser/translate/buildflags/buildflags.gni") import("//brave/components/brave_ads/browser/buildflags/buildflags.gni") import("//brave/components/brave_rewards/browser/buildflags/buildflags.gni") +import("//brave/components/brave_sync/buildflags/buildflags.gni") import("//brave/components/brave_wallet/browser/buildflags/buildflags.gni") import("//testing/test.gni") import("//third_party/widevine/cdm/widevine.gni") @@ -90,9 +91,6 @@ test("brave_unit_tests") { "//brave/components/assist_ranker/ranker_model_loader_impl_unittest.cc", "//brave/components/brave_shields/browser/ad_block_regional_service_unittest.cc", "//brave/components/brave_shields/browser/https_everywhere_recently_used_cache_unittest.cpp", - "//brave/components/brave_sync/bookmark_order_util_unittest.cc", - "//brave/components/brave_sync/brave_sync_service_unittest.cc", - "//brave/components/brave_sync/client/bookmark_change_processor_unittest.cc", "//brave/components/brave_webtorrent/browser/net/brave_torrent_redirect_network_delegate_helper_unittest.cc", "//brave/components/invalidation/fcm_unittest.cc", "//brave/components/gcm_driver/gcm_unittest.cc", @@ -169,6 +167,14 @@ test("brave_unit_tests") { ] } + if (enable_brave_sync) { + sources += [ + "//brave/components/brave_sync/bookmark_order_util_unittest.cc", + "//brave/components/brave_sync/brave_sync_service_unittest.cc", + "//brave/components/brave_sync/syncer_helper_unittest.cc", + ] + } + if (enable_tor) { sources += [ "//brave/browser/profiles/tor_unittest_profile_manager.cc", @@ -224,7 +230,6 @@ test("brave_unit_tests") { deps = [ "//brave/components/brave_rewards/browser:testutil", "//brave/components/brave_ads/browser:testutil", - "//brave/components/brave_sync:testutil", "//brave/vendor/bat-native-rapidjson", "//brave/vendor/brave_base", "//chrome:browser_dependencies", @@ -255,6 +260,12 @@ test("brave_unit_tests") { configs += [ "//brave/vendor/bat-native-confirmations:internal_config" ] } + if (enable_brave_sync) { + deps += [ + "//brave/components/brave_sync:testutil", + ] + } + if (bundle_widevine_cdm) { sources += [ "//brave/browser/widevine/brave_widevine_bundle_manager_unittest.cc",