diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd index 3f786912ca0a..b88f36827684 100644 --- a/app/brave_generated_resources.grd +++ b/app/brave_generated_resources.grd @@ -154,6 +154,9 @@ Brave Payments + + Open windows and tabs + Widevine is not installed diff --git a/browser/brave_profile_prefs.cc b/browser/brave_profile_prefs.cc index 79b41ef1f34d..236b848ee955 100644 --- a/browser/brave_profile_prefs.cc +++ b/browser/brave_profile_prefs.cc @@ -83,6 +83,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref(prefs::kImportDialogCookies, true); registry->RegisterBooleanPref(prefs::kImportDialogStats, true); registry->RegisterBooleanPref(prefs::kImportDialogLedger, true); + registry->RegisterBooleanPref(prefs::kImportDialogWindows, true); // Importer: ledger (used for Brave Rewards pinned => tips) registry->RegisterIntegerPref(kBravePaymentsPinnedItemCount, 0); } diff --git a/browser/extensions/api/settings_private/brave_prefs_util.cc b/browser/extensions/api/settings_private/brave_prefs_util.cc index f4b54b6131c2..e4754544a0be 100644 --- a/browser/extensions/api/settings_private/brave_prefs_util.cc +++ b/browser/extensions/api/settings_private/brave_prefs_util.cc @@ -30,6 +30,8 @@ const PrefsUtil::TypedPrefMap& BravePrefsUtil::GetWhitelistedKeys() { settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_brave_whitelist)[::prefs::kImportDialogLedger] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_brave_whitelist)[::prefs::kImportDialogWindows] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Default Brave shields (*s_brave_whitelist)[kHTTPSEVerywhereControlType] = settings_api::PrefType::PREF_TYPE_BOOLEAN; diff --git a/browser/importer/brave_external_process_importer_client.cc b/browser/importer/brave_external_process_importer_client.cc index 779bfaa0e361..5b26d82ef638 100644 --- a/browser/importer/brave_external_process_importer_client.cc +++ b/browser/importer/brave_external_process_importer_client.cc @@ -69,4 +69,12 @@ void BraveExternalProcessImporterClient::OnReferralImportReady( bridge_->UpdateReferral(referral); } +void BraveExternalProcessImporterClient::OnWindowsImportReady( + const ImportedWindowState& windowState) { + if (cancelled_) + return; + + bridge_->UpdateWindows(windowState); +} + BraveExternalProcessImporterClient::~BraveExternalProcessImporterClient() {} diff --git a/browser/importer/brave_external_process_importer_client.h b/browser/importer/brave_external_process_importer_client.h index 6a706af80ba6..3b33d4a60f1e 100644 --- a/browser/importer/brave_external_process_importer_client.h +++ b/browser/importer/brave_external_process_importer_client.h @@ -13,6 +13,7 @@ struct BraveStats; struct BraveLedger; +struct ImportedWindowState; class BraveExternalProcessImporterClient : public ExternalProcessImporterClient { public: @@ -35,6 +36,8 @@ class BraveExternalProcessImporterClient : public ExternalProcessImporterClient const BraveLedger& ledger) override; void OnReferralImportReady( const BraveReferral& referral) override; + void OnWindowsImportReady( + const ImportedWindowState& windowState) override; private: ~BraveExternalProcessImporterClient() override; diff --git a/browser/importer/brave_in_process_importer_bridge.cc b/browser/importer/brave_in_process_importer_bridge.cc index 8046ff88fe32..ad1d6c92471a 100644 --- a/browser/importer/brave_in_process_importer_bridge.cc +++ b/browser/importer/brave_in_process_importer_bridge.cc @@ -40,4 +40,10 @@ void BraveInProcessImporterBridge::UpdateReferral(const BraveReferral& referral) writer_->UpdateReferral(referral); } +void BraveInProcessImporterBridge::UpdateWindows( + const ImportedWindowState& windowState) { + // TODO: Can we just restore windows/tabs here? Do we even need to do anything with the ProfileWriter? + writer_->UpdateWindows(windowState); +} + BraveInProcessImporterBridge::~BraveInProcessImporterBridge() {} diff --git a/browser/importer/brave_in_process_importer_bridge.h b/browser/importer/brave_in_process_importer_bridge.h index 67b6de77bbdc..69501e247b4f 100644 --- a/browser/importer/brave_in_process_importer_bridge.h +++ b/browser/importer/brave_in_process_importer_bridge.h @@ -28,6 +28,7 @@ class BraveInProcessImporterBridge : public InProcessImporterBridge { void UpdateStats(const BraveStats& stats) override; void UpdateLedger(const BraveLedger& ledger) override; void UpdateReferral(const BraveReferral& referral) override; + void UpdateWindows(const ImportedWindowState& windowState) override; void FinishLedgerImport(); void Cancel(); diff --git a/browser/importer/brave_profile_writer.cc b/browser/importer/brave_profile_writer.cc index e5bede19c5f8..6ea74c9e7d28 100644 --- a/browser/importer/brave_profile_writer.cc +++ b/browser/importer/brave_profile_writer.cc @@ -5,6 +5,7 @@ #include "brave/browser/importer/brave_profile_writer.h" #include "brave/common/importer/brave_stats.h" #include "brave/common/importer/brave_referral.h" +#include "brave/common/importer/imported_browser_window.h" #include "brave/common/pref_names.h" #include "brave/components/brave_rewards/browser/rewards_service.h" #include "brave/components/brave_rewards/browser/rewards_service_factory.h" @@ -19,6 +20,12 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" @@ -28,6 +35,7 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "services/network/public/mojom/cookie_manager.mojom.h" +#include "ui/base/ui_base_types.h" #include @@ -81,7 +89,6 @@ void BraveProfileWriter::UpdateStats(const BraveStats& stats) { https_upgrades + stats.httpsEverywhere_count); } } - void BraveProfileWriter::SetBridge(BraveInProcessImporterBridge* bridge) { bridge_ptr_ = bridge; } @@ -316,3 +323,87 @@ void BraveProfileWriter::UpdateReferral(const BraveReferral& referral) { local_state->ClearPref(kReferralTimestamp); } } + +Browser* OpenImportedBrowserWindow( + const ImportedBrowserWindow& window, + Profile* profile) { + Browser::CreateParams params(Browser::TYPE_TABBED, profile, false); + + params.initial_bounds = gfx::Rect(window.top, window.left, + window.width, window.height); + + ui::WindowShowState show_state = ui::SHOW_STATE_DEFAULT; + if (window.state == "normal") { + show_state = ui::SHOW_STATE_NORMAL; + } else if (window.state == "minimized") { + show_state = ui::SHOW_STATE_MINIMIZED; + } else if (window.state == "maximized") { + show_state = ui::SHOW_STATE_MAXIMIZED; + } else if (window.state == "fullscreen") { + show_state = ui::SHOW_STATE_FULLSCREEN; + } + params.initial_show_state = show_state; + + return new Browser(params); +} + +void OpenImportedBrowserTabs(Browser* browser, + const std::vector& tabs, + bool pinned) { + for (const auto tab : tabs) { + NavigateParams params(browser, tab.location, + ui::PAGE_TRANSITION_AUTO_TOPLEVEL); + params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB; + params.tabstrip_add_types = pinned ? TabStripModel::ADD_PINNED + : TabStripModel::ADD_FORCE_INDEX; + Navigate(¶ms); + } +} + +int GetSelectedTabIndex(const ImportedBrowserWindow& window) { + // The window has an activeFrameKey, which may be equal to the key for one of + // its tabs. Find the matching tab, if one exists, and return its index in + // the tabs vector. + for (int i = 0; i < (int)window.tabs.size(); i++) { + if (window.activeFrameKey == window.tabs[i].key) + return i; + } + + // If there was no matching tab, default to returning the index of the + // right-most tab. + return window.tabs.size() - 1; +} + +void ShowBrowser(Browser* browser, int selected_tab_index) { + DCHECK(browser); + DCHECK(browser->tab_strip_model()->count()); + browser->tab_strip_model()->ActivateTabAt(selected_tab_index, true); + browser->window()->Show(); + browser->tab_strip_model()->GetActiveWebContents()->SetInitialFocus(); +} + +void PrependPinnedTabs(Browser* browser, + const std::vector& tabs) { + OpenImportedBrowserTabs(browser, tabs, true); +} + +void BraveProfileWriter::UpdateWindows( + const ImportedWindowState& windowState) { + Browser* active = chrome::FindBrowserWithActiveWindow(); + Browser* first = nullptr; + + for (const auto window : windowState.windows) { + Browser* browser = OpenImportedBrowserWindow(window, profile_); + OpenImportedBrowserTabs(browser, window.tabs, false); + ShowBrowser(browser, GetSelectedTabIndex(window)); + + if (!first) + first = browser; + } + + PrependPinnedTabs(first, windowState.pinnedTabs); + + // Re-focus the window that was originally focused before import. + if (active) + active->window()->Show(); +} diff --git a/browser/importer/brave_profile_writer.h b/browser/importer/brave_profile_writer.h index fb4d2be07a76..70f9c7763585 100644 --- a/browser/importer/brave_profile_writer.h +++ b/browser/importer/brave_profile_writer.h @@ -16,6 +16,7 @@ struct BraveStats; struct BraveReferral; class BraveInProcessImporterBridge; +struct ImportedWindowState; class BraveProfileWriter : public ProfileWriter, public brave_rewards::RewardsServiceObserver { @@ -26,6 +27,7 @@ class BraveProfileWriter : public ProfileWriter, virtual void UpdateStats(const BraveStats& stats); virtual void UpdateLedger(const BraveLedger& ledger); virtual void UpdateReferral(const BraveReferral& referral); + virtual void UpdateWindows(const ImportedWindowState& windowState); void SetBridge(BraveInProcessImporterBridge* bridge); diff --git a/chromium_src/chrome/browser/importer/external_process_importer_client.h b/chromium_src/chrome/browser/importer/external_process_importer_client.h index ccbfa4759f0b..280c8a99eb33 100644 --- a/chromium_src/chrome/browser/importer/external_process_importer_client.h +++ b/chromium_src/chrome/browser/importer/external_process_importer_client.h @@ -6,5 +6,6 @@ struct BraveLedger; struct BraveStats; +struct ImportedWindowState; #include "../../../../../chrome/browser/importer/external_process_importer_client.h" diff --git a/chromium_src/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chromium_src/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 2c691494f0c3..b59b6d864a76 100644 --- a/chromium_src/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chromium_src/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc @@ -13,6 +13,7 @@ void BraveAddImportDataStrings(content::WebUIDataSource* html_source) { {"importCookies", IDS_SETTINGS_IMPORT_COOKIES_CHECKBOX}, {"importStats", IDS_SETTINGS_IMPORT_STATS_CHECKBOX}, {"importLedger", IDS_SETTINGS_IMPORT_LEDGER_CHECKBOX}, + {"importWindows", IDS_SETTINGS_IMPORT_WINDOWS_CHECKBOX}, }; AddLocalizedStringsBulk(html_source, localized_strings, arraysize(localized_strings)); diff --git a/chromium_src/chrome/common/importer/importer_bridge.h b/chromium_src/chrome/common/importer/importer_bridge.h index cba6fcf5ba76..2985001e4f74 100644 --- a/chromium_src/chrome/common/importer/importer_bridge.h +++ b/chromium_src/chrome/common/importer/importer_bridge.h @@ -7,5 +7,6 @@ struct BraveLedger; struct BraveStats; struct BraveReferral; +struct ImportedWindowState; #include "../../../../../chrome/common/importer/importer_bridge.h" diff --git a/chromium_src/chrome/common/importer/profile_import_process_param_traits_macros.h b/chromium_src/chrome/common/importer/profile_import_process_param_traits_macros.h index 30e7b7a6aa59..92ec8e5cc021 100644 --- a/chromium_src/chrome/common/importer/profile_import_process_param_traits_macros.h +++ b/chromium_src/chrome/common/importer/profile_import_process_param_traits_macros.h @@ -3,6 +3,7 @@ #include "brave/common/importer/brave_ledger.h" #include "brave/common/importer/brave_referral.h" #include "brave/common/importer/brave_stats.h" +#include "brave/common/importer/imported_browser_window.h" IPC_STRUCT_TRAITS_BEGIN(BraveStats) IPC_STRUCT_TRAITS_MEMBER(adblock_count) @@ -45,3 +46,24 @@ IPC_STRUCT_TRAITS_BEGIN(BraveReferral) IPC_STRUCT_TRAITS_MEMBER(finalize_timestamp) IPC_STRUCT_TRAITS_MEMBER(week_of_installation) IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(ImportedBrowserTab) + IPC_STRUCT_TRAITS_MEMBER(key) + IPC_STRUCT_TRAITS_MEMBER(location) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(ImportedBrowserWindow) + IPC_STRUCT_TRAITS_MEMBER(top) + IPC_STRUCT_TRAITS_MEMBER(left) + IPC_STRUCT_TRAITS_MEMBER(width) + IPC_STRUCT_TRAITS_MEMBER(height) + IPC_STRUCT_TRAITS_MEMBER(focused) + IPC_STRUCT_TRAITS_MEMBER(state) + IPC_STRUCT_TRAITS_MEMBER(activeFrameKey) + IPC_STRUCT_TRAITS_MEMBER(tabs) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(ImportedWindowState) + IPC_STRUCT_TRAITS_MEMBER(windows) + IPC_STRUCT_TRAITS_MEMBER(pinnedTabs) +IPC_STRUCT_TRAITS_END() diff --git a/chromium_src/chrome/common/pref_names.cc b/chromium_src/chrome/common/pref_names.cc index e529e2e93aa6..34757490e167 100644 --- a/chromium_src/chrome/common/pref_names.cc +++ b/chromium_src/chrome/common/pref_names.cc @@ -5,5 +5,6 @@ namespace prefs { const char kImportDialogCookies[] = "import_dialog_cookies"; const char kImportDialogStats[] = "import_dialog_stats"; const char kImportDialogLedger[] = "import_dialog_ledger"; +const char kImportDialogWindows[] = "import_dialog_windows"; -} // namespace prefs \ No newline at end of file +} // namespace prefs diff --git a/chromium_src/chrome/common/pref_names.h b/chromium_src/chrome/common/pref_names.h index 065b254175ea..ecf039226c5c 100644 --- a/chromium_src/chrome/common/pref_names.h +++ b/chromium_src/chrome/common/pref_names.h @@ -5,5 +5,6 @@ namespace prefs { extern const char kImportDialogCookies[]; extern const char kImportDialogStats[]; extern const char kImportDialogLedger[]; +extern const char kImportDialogWindows[]; -} // namespace prefs \ No newline at end of file +} // namespace prefs diff --git a/common/BUILD.gn b/common/BUILD.gn index f830b9914c11..635dd33b7729 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -20,6 +20,8 @@ source_set("common") { "brave_switches.h", "importer/brave_referral.cc", "importer/brave_referral.h", + "importer/imported_browser_window.cc", + "importer/imported_browser_window.h", "pref_names.cc", "pref_names.h", "webui_url_constants.cc", diff --git a/common/importer/brave_importer_utils.cc b/common/importer/brave_importer_utils.cc index 68234da59691..32ecb671f12a 100644 --- a/common/importer/brave_importer_utils.cc +++ b/common/importer/brave_importer_utils.cc @@ -27,7 +27,8 @@ bool BraveImporterCanImport(const base::FilePath& profile, profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("ledger-state.json"))); if (base::PathExists(session_store)) - *services_supported |= importer::HISTORY | importer::FAVORITES | importer::STATS; + *services_supported |= importer::HISTORY | importer::FAVORITES | + importer::STATS | importer::WINDOWS; if (base::PathExists(passwords)) *services_supported |= importer::PASSWORDS; if (base::PathExists(cookies)) diff --git a/common/importer/brave_mock_importer_bridge.h b/common/importer/brave_mock_importer_bridge.h index 721e5650aa51..e7b85be18707 100644 --- a/common/importer/brave_mock_importer_bridge.h +++ b/common/importer/brave_mock_importer_bridge.h @@ -9,6 +9,7 @@ #include "brave/common/importer/brave_ledger.h" #include "brave/common/importer/brave_stats.h" +#include "brave/common/importer/imported_browser_window.h" #include "chrome/common/importer/mock_importer_bridge.h" #include "net/cookies/canonical_cookie.h" #include "testing/gmock/include/gmock/gmock.h" @@ -26,6 +27,8 @@ class BraveMockImporterBridge : public MockImporterBridge { void(const BraveStats&)); MOCK_METHOD1(UpdateLedger, void(const BraveLedger&)); + MOCK_METHOD1(UpdateWindows, + void(const ImportedWindowState&)); private: ~BraveMockImporterBridge() override; diff --git a/common/importer/imported_browser_window.cc b/common/importer/imported_browser_window.cc new file mode 100644 index 000000000000..840cc1aa68e0 --- /dev/null +++ b/common/importer/imported_browser_window.cc @@ -0,0 +1,17 @@ +/* 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/common/importer/imported_browser_window.h" + +ImportedBrowserTab::ImportedBrowserTab() {} +ImportedBrowserTab::ImportedBrowserTab(const ImportedBrowserTab& other) = default; +ImportedBrowserTab::~ImportedBrowserTab() {} + +ImportedBrowserWindow::ImportedBrowserWindow() {} +ImportedBrowserWindow::ImportedBrowserWindow(const ImportedBrowserWindow& other) = default; +ImportedBrowserWindow::~ImportedBrowserWindow() {} + +ImportedWindowState::ImportedWindowState() {} +ImportedWindowState::ImportedWindowState(const ImportedWindowState& other) = default; +ImportedWindowState::~ImportedWindowState() {} diff --git a/common/importer/imported_browser_window.h b/common/importer/imported_browser_window.h new file mode 100644 index 000000000000..f63631f574e4 --- /dev/null +++ b/common/importer/imported_browser_window.h @@ -0,0 +1,54 @@ +/* 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_COMMON_IMPORTER_IMPORTED_BROWSER_WINDOW_H_ +#define BRAVE_COMMON_IMPORTER_IMPORTED_BROWSER_WINDOW_H_ + +#include +#include +#include "url/gurl.h" + +struct ImportedBrowserTab { + ImportedBrowserTab(); + ImportedBrowserTab(const ImportedBrowserTab& other); + ~ImportedBrowserTab(); + + int key; + GURL location; +}; + +struct ImportedBrowserWindow { + ImportedBrowserWindow(); + ImportedBrowserWindow(const ImportedBrowserWindow& other); + ~ImportedBrowserWindow(); + + int top; + int left; + int width; + int height; + + bool focused; + + // "normal", "minimized", "maximized", or "fullscreen" + std::string state; + + // Warning: activeFrameKey may not reference an existing key in the frames + // Array. For example, if a private or private w/ Tor tab was focused when the + // browser closed, it will be the activeFrameKey, but it will not be + // persisted. + int activeFrameKey; + + std::vector tabs; +}; + +struct ImportedWindowState { + ImportedWindowState(); + ImportedWindowState(const ImportedWindowState& other); + ~ImportedWindowState(); + + std::vector windows; + std::vector pinnedTabs; +}; + +#endif // BRAVE_COMMON_IMPORTER_IMPORTED_BROWSER_WINDOW_H_ diff --git a/patches/chrome-browser-importer-external_process_importer_client.h.patch b/patches/chrome-browser-importer-external_process_importer_client.h.patch index c4e5dbda814e..6b2622eb1775 100644 --- a/patches/chrome-browser-importer-external_process_importer_client.h.patch +++ b/patches/chrome-browser-importer-external_process_importer_client.h.patch @@ -1,8 +1,8 @@ diff --git a/chrome/browser/importer/external_process_importer_client.h b/chrome/browser/importer/external_process_importer_client.h -index 9451b0917536e73b42c596527112d3119b2c4cc5..3e25ca767319375901939cdbc26edfa796b12bde 100644 +index 9451b0917536e73b42c596527112d3119b2c4cc5..72c36c03d19db2d3cf8b5358edcb295bb6bc9179 100644 --- a/chrome/browser/importer/external_process_importer_client.h +++ b/chrome/browser/importer/external_process_importer_client.h -@@ -85,6 +85,11 @@ class ExternalProcessImporterClient +@@ -85,6 +85,12 @@ class ExternalProcessImporterClient void OnAutofillFormDataImportGroup( const std::vector& autofill_form_data_entry_group) override; @@ -11,6 +11,7 @@ index 9451b0917536e73b42c596527112d3119b2c4cc5..3e25ca767319375901939cdbc26edfa7 + void OnStatsImportReady(const BraveStats& stats) override {}; + void OnLedgerImportReady(const BraveLedger& ledger) override {}; + void OnReferralImportReady(const BraveReferral& referral) override {}; ++ void OnWindowsImportReady(const ImportedWindowState& window_state) override {}; protected: ~ExternalProcessImporterClient() override; diff --git a/patches/chrome-browser-resources-settings-people_page-import_data_dialog.html.patch b/patches/chrome-browser-resources-settings-people_page-import_data_dialog.html.patch index 27067c64682c..c9bb060b2cb8 100644 --- a/patches/chrome-browser-resources-settings-people_page-import_data_dialog.html.patch +++ b/patches/chrome-browser-resources-settings-people_page-import_data_dialog.html.patch @@ -1,8 +1,8 @@ diff --git a/chrome/browser/resources/settings/people_page/import_data_dialog.html b/chrome/browser/resources/settings/people_page/import_data_dialog.html -index fdd6f9d2265fe069d159ceed6e1e7ec561a2915e..361dec27b7f52fe765798e1b8c2cfb56ebeb61c3 100644 +index fdd6f9d2265fe069d159ceed6e1e7ec561a2915e..1d06434794a2605944dceff05381d0b777bef28a 100644 --- a/chrome/browser/resources/settings/people_page/import_data_dialog.html +++ b/chrome/browser/resources/settings/people_page/import_data_dialog.html -@@ -94,6 +94,22 @@ +@@ -94,6 +94,26 @@ pref="{{prefs.import_dialog_autofill_form_data}}" label="$i18n{importAutofillFormData}"> @@ -21,7 +21,11 @@ index fdd6f9d2265fe069d159ceed6e1e7ec561a2915e..361dec27b7f52fe765798e1b8c2cfb56 + pref="{{prefs.import_dialog_ledger}}" + label="$i18n{importLedger}"> + -+ ++
diff --git a/patches/chrome-browser-resources-settings-people_page-import_data_dialog.js.patch b/patches/chrome-browser-resources-settings-people_page-import_data_dialog.js.patch index fd816cdbe08e..48bd85a4ce92 100644 --- a/patches/chrome-browser-resources-settings-people_page-import_data_dialog.js.patch +++ b/patches/chrome-browser-resources-settings-people_page-import_data_dialog.js.patch @@ -1,8 +1,8 @@ diff --git a/chrome/browser/resources/settings/people_page/import_data_dialog.js b/chrome/browser/resources/settings/people_page/import_data_dialog.js -index f59448f4b4a25ab8b5e13c23feafa7957e83fa82..2d331bf9a60643ca0d92cba645acd3854d6af415 100644 +index f59448f4b4a25ab8b5e13c23feafa7957e83fa82..c6b7510e288db3dc6259ca80730f62235b1220d3 100644 --- a/chrome/browser/resources/settings/people_page/import_data_dialog.js +++ b/chrome/browser/resources/settings/people_page/import_data_dialog.js -@@ -84,7 +84,13 @@ Polymer({ +@@ -84,7 +84,15 @@ Polymer({ !(this.getPref('import_dialog_search_engine').value && this.selected_.search) && !(this.getPref('import_dialog_autofill_form_data').value && @@ -13,7 +13,9 @@ index f59448f4b4a25ab8b5e13c23feafa7957e83fa82..2d331bf9a60643ca0d92cba645acd385 + !(this.getPref('import_dialog_stats').value && + this.selected_.stats) && + !(this.getPref('import_dialog_ledger').value && -+ this.selected_.ledger); ++ this.selected_.ledger) && ++ !(this.getPref('import_dialog_windows').value && ++ this.selected_.windows); }, /** diff --git a/patches/chrome-browser-ui-webui-settings-settings_import_data_handler.cc.patch b/patches/chrome-browser-ui-webui-settings-settings_import_data_handler.cc.patch index 15a4e640e1e2..2e3e69ff5c52 100644 --- a/patches/chrome-browser-ui-webui-settings-settings_import_data_handler.cc.patch +++ b/patches/chrome-browser-ui-webui-settings-settings_import_data_handler.cc.patch @@ -1,5 +1,5 @@ diff --git a/chrome/browser/ui/webui/settings/settings_import_data_handler.cc b/chrome/browser/ui/webui/settings/settings_import_data_handler.cc -index 32deebd14fb3383010af01381af9b34442d19b6e..ad94e6f86baa371f8c0fd4a976cfac28e612969d 100644 +index 32deebd14fb3383010af01381af9b34442d19b6e..823ce59a8e13a49965cb5d7026fa9d7f426de740 100644 --- a/chrome/browser/ui/webui/settings/settings_import_data_handler.cc +++ b/chrome/browser/ui/webui/settings/settings_import_data_handler.cc @@ -18,6 +18,8 @@ @@ -26,7 +26,7 @@ index 32deebd14fb3383010af01381af9b34442d19b6e..ad94e6f86baa371f8c0fd4a976cfac28 importer::LogImporterUseToMetrics("ImportDataHandler", source_profile.importer_type); -@@ -126,6 +128,12 @@ void ImportDataHandler::ImportData(const base::ListValue* args) { +@@ -126,6 +128,14 @@ void ImportDataHandler::ImportData(const base::ListValue* args) { selected_items |= importer::PASSWORDS; if (prefs->GetBoolean(prefs::kImportDialogSearchEngine)) selected_items |= importer::SEARCH_ENGINES; @@ -36,10 +36,12 @@ index 32deebd14fb3383010af01381af9b34442d19b6e..ad94e6f86baa371f8c0fd4a976cfac28 + selected_items |= importer::STATS; + if (prefs->GetBoolean(prefs::kImportDialogLedger)) + selected_items |= importer::LEDGER; ++ if (prefs->GetBoolean(prefs::kImportDialogWindows)) ++ selected_items |= importer::WINDOWS; const importer::SourceProfile& source_profile = importer_list_->GetSourceProfileAt(browser_index); -@@ -179,6 +187,12 @@ void ImportDataHandler::SendBrowserProfileData(const std::string& callback_id) { +@@ -179,6 +189,14 @@ void ImportDataHandler::SendBrowserProfileData(const std::string& callback_id) { browser_profile->SetBoolean( "autofillFormData", (browser_services & importer::AUTOFILL_FORM_DATA) != 0); @@ -49,6 +51,8 @@ index 32deebd14fb3383010af01381af9b34442d19b6e..ad94e6f86baa371f8c0fd4a976cfac28 + (browser_services & importer::STATS) != 0); + browser_profile->SetBoolean("ledger", + (browser_services & importer::LEDGER) != 0); ++ browser_profile->SetBoolean("windows", ++ (browser_services & importer::WINDOWS) != 0); browser_profiles.Append(std::move(browser_profile)); } diff --git a/patches/chrome-common-importer-importer_bridge.h.patch b/patches/chrome-common-importer-importer_bridge.h.patch index 4ef322a4631d..a0a06243a342 100644 --- a/patches/chrome-common-importer-importer_bridge.h.patch +++ b/patches/chrome-common-importer-importer_bridge.h.patch @@ -1,8 +1,8 @@ diff --git a/chrome/common/importer/importer_bridge.h b/chrome/common/importer/importer_bridge.h -index b4250c91d1b83ea920b3de9cd6b1a7929b30ffc5..9cc21253653ca8add3fac72462ed1010bb97f988 100644 +index b4250c91d1b83ea920b3de9cd6b1a7929b30ffc5..d36edb5a93f0d0117bb368c15693e8fc91272d3c 100644 --- a/chrome/common/importer/importer_bridge.h +++ b/chrome/common/importer/importer_bridge.h -@@ -58,6 +58,18 @@ class ImporterBridge : public base::RefCountedThreadSafe { +@@ -58,6 +58,21 @@ class ImporterBridge : public base::RefCountedThreadSafe { virtual void SetAutofillFormData( const std::vector& entries) = 0; @@ -17,6 +17,9 @@ index b4250c91d1b83ea920b3de9cd6b1a7929b30ffc5..9cc21253653ca8add3fac72462ed1010 + + virtual void UpdateReferral( + const BraveReferral& referral) {}; ++ ++ virtual void UpdateWindows( ++ const ImportedWindowState& windowState) {}; + // Notifies the coordinator that the import operation has begun. virtual void NotifyStarted() = 0; diff --git a/patches/chrome-common-importer-importer_data_types.h.patch b/patches/chrome-common-importer-importer_data_types.h.patch index 62d833680de9..38b42847f6cc 100644 --- a/patches/chrome-common-importer-importer_data_types.h.patch +++ b/patches/chrome-common-importer-importer_data_types.h.patch @@ -1,19 +1,20 @@ diff --git a/chrome/common/importer/importer_data_types.h b/chrome/common/importer/importer_data_types.h -index 0fc90c62398a93eb89568ce78c8ded2bc9b232b6..e27ec2fe408eea77390a080abf697a393a9cd517 100644 +index 0fc90c62398a93eb89568ce78c8ded2bc9b232b6..91632164e1b45fafb5befb71557993c87fe29462 100644 --- a/chrome/common/importer/importer_data_types.h +++ b/chrome/common/importer/importer_data_types.h -@@ -31,7 +31,9 @@ enum ImportItem { +@@ -31,7 +31,10 @@ enum ImportItem { SEARCH_ENGINES = 1 << 4, HOME_PAGE = 1 << 5, AUTOFILL_FORM_DATA = 1 << 6, - ALL = (1 << 7) - 1 // All the bits should be 1, hence the -1. + STATS = 1 << 7, + LEDGER = 1 << 8, -+ ALL = (1 << 9) - 1 // All the bits should be 1, hence the -1. ++ WINDOWS = 1 << 9, ++ ALL = (1 << 10) - 1 // All the bits should be 1, hence the -1. }; // Information about a profile needed by an importer to do import work. -@@ -83,6 +85,8 @@ enum VisitSource { +@@ -83,6 +86,8 @@ enum VisitSource { VISIT_SOURCE_FIREFOX_IMPORTED = 1, VISIT_SOURCE_IE_IMPORTED = 2, VISIT_SOURCE_SAFARI_IMPORTED = 3, diff --git a/patches/chrome-common-importer-profile_import.mojom.patch b/patches/chrome-common-importer-profile_import.mojom.patch index efdea516c94b..fc13ba3d9240 100644 --- a/patches/chrome-common-importer-profile_import.mojom.patch +++ b/patches/chrome-common-importer-profile_import.mojom.patch @@ -1,5 +1,5 @@ diff --git a/chrome/common/importer/profile_import.mojom b/chrome/common/importer/profile_import.mojom -index 081955be7142f8a1ffdd68e19e30baa3b303586e..f60a769d673136f5037c565e08d221a39f06de32 100644 +index 081955be7142f8a1ffdd68e19e30baa3b303586e..f73b88a374a18a69b9551cf3f702ebdd5992d11d 100644 --- a/chrome/common/importer/profile_import.mojom +++ b/chrome/common/importer/profile_import.mojom @@ -6,6 +6,7 @@ module chrome.mojom; @@ -10,7 +10,7 @@ index 081955be7142f8a1ffdd68e19e30baa3b303586e..f60a769d673136f5037c565e08d221a3 import "url/mojom/url.mojom"; const string kProfileImportServiceName = "profile_import"; -@@ -31,6 +32,15 @@ struct FaviconUsageDataList; +@@ -31,6 +32,24 @@ struct FaviconUsageDataList; [Native] struct ImporterIE7PasswordInfo; @@ -22,11 +22,20 @@ index 081955be7142f8a1ffdd68e19e30baa3b303586e..f60a769d673136f5037c565e08d221a3 + +[Native] +struct BraveReferral; ++ ++[Native] ++struct ImportedBrowserTab; ++ ++[Native] ++struct ImportedBrowserWindow; ++ ++[Native] ++struct ImportedWindowState; + [Native] enum ImportItem; -@@ -64,6 +74,11 @@ interface ProfileImportObserver { +@@ -64,6 +83,12 @@ interface ProfileImportObserver { OnAutofillFormDataImportStart(uint32 total_autofill_form_data_entry_count); OnAutofillFormDataImportGroup( array autofill_form_data_entry_group); @@ -35,6 +44,7 @@ index 081955be7142f8a1ffdd68e19e30baa3b303586e..f60a769d673136f5037c565e08d221a3 + OnStatsImportReady(BraveStats stats); + OnLedgerImportReady(BraveLedger ledger); + OnReferralImportReady(BraveReferral referral); ++ OnWindowsImportReady(ImportedWindowState window_state); }; // This interface is used to control the import process. diff --git a/patches/chrome-common-importer-profile_import.typemap.patch b/patches/chrome-common-importer-profile_import.typemap.patch index 0989dcef6a23..afe973b45cbb 100644 --- a/patches/chrome-common-importer-profile_import.typemap.patch +++ b/patches/chrome-common-importer-profile_import.typemap.patch @@ -1,18 +1,19 @@ diff --git a/chrome/common/importer/profile_import.typemap b/chrome/common/importer/profile_import.typemap -index 6283f2bf6871a10f710694772b5da0bc9b70c2ad..aff217801c7c8a2d6c1bdeeded1c266122a66302 100644 +index 6283f2bf6871a10f710694772b5da0bc9b70c2ad..e11821c72ba2d1adc36c6ca6d362f10a5f501b66 100644 --- a/chrome/common/importer/profile_import.typemap +++ b/chrome/common/importer/profile_import.typemap -@@ -4,6 +4,9 @@ +@@ -4,6 +4,10 @@ mojom = "//chrome/common/importer/profile_import.mojom" public_headers = [ + "//brave/common/importer/brave_ledger.h", + "//brave/common/importer/brave_stats.h", + "//brave/common/importer/brave_referral.h", ++ "//brave/common/importer/imported_browser_window.h", "//chrome/common/importer/imported_bookmark_entry.h", "//chrome/common/importer/importer_autofill_form_data_entry.h", "//chrome/common/importer/importer_data_types.h", -@@ -13,6 +16,7 @@ public_headers = [ +@@ -13,6 +17,7 @@ public_headers = [ traits_headers = [ "//chrome/common/importer/profile_import_process_param_traits.h" ] deps = [ @@ -20,11 +21,14 @@ index 6283f2bf6871a10f710694772b5da0bc9b70c2ad..aff217801c7c8a2d6c1bdeeded1c2661 "//chrome/common", "//components/favicon_base", "//ipc", -@@ -26,4 +30,7 @@ type_mappings = [ +@@ -26,4 +31,10 @@ type_mappings = [ "chrome.mojom.SearchEngineInfo=::importer::SearchEngineInfo", "chrome.mojom.SourceProfile=::importer::SourceProfile", "chrome.mojom.ImportItem=::importer::ImportItem", + "chrome.mojom.BraveStats=::BraveStats", + "chrome.mojom.BraveLedger=::BraveLedger", + "chrome.mojom.BraveReferral=::BraveReferral", ++ "chrome.mojom.ImportedBrowserTab=::ImportedBrowserTab", ++ "chrome.mojom.ImportedBrowserWindow=::ImportedBrowserWindow", ++ "chrome.mojom.ImportedWindowState=::ImportedWindowState", ] diff --git a/utility/importer/brave_external_process_importer_bridge.cc b/utility/importer/brave_external_process_importer_bridge.cc index b3dea84b2020..c221c52d423b 100644 --- a/utility/importer/brave_external_process_importer_bridge.cc +++ b/utility/importer/brave_external_process_importer_bridge.cc @@ -54,6 +54,11 @@ void BraveExternalProcessImporterBridge::UpdateReferral( (*observer_)->OnReferralImportReady(referral); } +void BraveExternalProcessImporterBridge::UpdateWindows( + const ImportedWindowState& windowState) { + (*observer_)->OnWindowsImportReady(windowState); +} + BraveExternalProcessImporterBridge::BraveExternalProcessImporterBridge( const base::flat_map& localized_strings, scoped_refptr observer) diff --git a/utility/importer/brave_external_process_importer_bridge.h b/utility/importer/brave_external_process_importer_bridge.h index 45d76cd3f7a9..4e4a25bee135 100644 --- a/utility/importer/brave_external_process_importer_bridge.h +++ b/utility/importer/brave_external_process_importer_bridge.h @@ -23,6 +23,7 @@ class BraveExternalProcessImporterBridge : void UpdateStats(const BraveStats& stats) override; void UpdateLedger(const BraveLedger& ledger) override; void UpdateReferral(const BraveReferral& referral) override; + void UpdateWindows(const ImportedWindowState& windowState) override; private: ~BraveExternalProcessImporterBridge() override; diff --git a/utility/importer/brave_importer.cc b/utility/importer/brave_importer.cc index f0ae9679eb74..5daa976feb3f 100644 --- a/utility/importer/brave_importer.cc +++ b/utility/importer/brave_importer.cc @@ -4,6 +4,7 @@ #include "brave/utility/importer/brave_importer.h" +#include #include #include #include @@ -18,6 +19,7 @@ #include "brave/common/importer/brave_ledger.h" #include "brave/common/importer/brave_stats.h" #include "brave/common/importer/brave_referral.h" +#include "brave/common/importer/imported_browser_window.h" #include "chrome/common/importer/importer_bridge.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/core/common/password_form.h" @@ -101,6 +103,12 @@ void BraveImporter::StartImport(const importer::SourceProfile& source_profile, bridge_->NotifyItemEnded(importer::STATS); } + if ((items & importer::WINDOWS) && !cancelled()) { + bridge_->NotifyItemStarted(importer::WINDOWS); + ImportWindows(); + bridge_->NotifyItemEnded(importer::WINDOWS); + } + if ((items & importer::LEDGER) && !cancelled()) { bridge_->NotifyItemStarted(importer::LEDGER); // NOTE: RecoverWallet is async. @@ -653,3 +661,151 @@ void BraveImporter::ImportReferral() { bridge_->UpdateReferral(referral); } + +std::vector ParseTabs(const base::Value* frames) { + std::vector tabs; + + for (const auto& frame : frames->GetList()) { + auto* key = frame.FindKeyOfType("key", + base::Value::Type::INTEGER); + auto* location = frame.FindKeyOfType("location", + base::Value::Type::STRING); + + if (!(key && location)) + continue; + + ImportedBrowserTab tab; + tab.key = key->GetInt(); + // TODO filter locations that won't work in b-c, e.g. about:preferences, about:newtab, chrome-extension:// (for PDFs), etc. + tab.location = GURL(location->GetString()); + + tabs.push_back(tab); + } + + return tabs; +} + +std::vector ParseWindows( + const base::Value* perWindowState) { + std::vector windows; + + for (const auto& entry : perWindowState->GetList()) { + ImportedBrowserWindow window; + + auto* windowInfo = entry.FindKeyOfType("windowInfo", + base::Value::Type::DICTIONARY); + auto* activeFrameKey = entry.FindKeyOfType("activeFrameKey", + base::Value::Type::INTEGER); + auto* frames = entry.FindKeyOfType("frames", + base::Value::Type::LIST); + + if (!(frames && activeFrameKey && windowInfo)) + continue; + + // Window info + auto* top = windowInfo->FindKeyOfType("top", + base::Value::Type::INTEGER); + auto* left = windowInfo->FindKeyOfType("left", + base::Value::Type::INTEGER); + auto* width = windowInfo->FindKeyOfType("width", + base::Value::Type::INTEGER); + auto* height = windowInfo->FindKeyOfType("height", + base::Value::Type::INTEGER); + auto* focused = windowInfo->FindKeyOfType("focused", + base::Value::Type::BOOLEAN); + auto* type = windowInfo->FindKeyOfType("type", + base::Value::Type::STRING); + auto* state = windowInfo->FindKeyOfType("state", + base::Value::Type::STRING); + + if (!(top && left && width && height && focused && type && state)) { + LOG(WARNING) << "windowInfo failed validation, skipping window"; + continue; + } + + // "type" is one of: "normal", "popup", or "devtools" + if (type->GetString() != "normal") { + LOG(INFO) << "windowInfo type not normal, skipping window"; + continue; + } + + window.top = top->GetInt(); + window.left = left->GetInt(); + window.width = width->GetInt(); + window.height = height->GetInt(); + window.focused = focused->GetBool(); + window.state = state->GetString(); + window.activeFrameKey = activeFrameKey->GetInt(); + + window.tabs = ParseTabs(frames); + + windows.push_back(window); + } + + return windows; +} + +std::vector ParsePinnedTabs( + const base::Value* pinnedSites) { + std::vector pinnedTabs; + + for (const auto& item : pinnedSites->DictItems()) { + const auto& value = item.second; + if (!value.is_dict()) + continue; + + const base::Value* location = + value.FindKeyOfType("location", + base::Value::Type::STRING); + const base::Value* order = + value.FindKeyOfType("order", + base::Value::Type::INTEGER); + + if (!(location && order)) + continue; + + ImportedBrowserTab tab; + tab.key = order->GetInt(); + tab.location = GURL(location->GetString()); + pinnedTabs.push_back(tab); + } + + // Sort pinned tabs by key, which corresponds to a 0-indexed ordering from + // left to right. + std::sort(std::begin(pinnedTabs), std::end(pinnedTabs), + [](auto a, auto b) { return a.key < b.key; }); + + return pinnedTabs; +} + +void BraveImporter::ImportWindows() { + std::unique_ptr session_store_json = ParseBraveStateFile( + "session-store-1"); + if (!session_store_json) + return; + + base::Value* perWindowState = + session_store_json->FindKeyOfType("perWindowState", + base::Value::Type::LIST); + base::Value* pinnedSites = + session_store_json->FindKeyOfType("pinnedSites", + base::Value::Type::DICTIONARY); + if (!(perWindowState && pinnedSites)) { + LOG(ERROR) << "perWindowState and/or pinnedSites not found"; + return; + } + + std::vector windows = ParseWindows(perWindowState); + + // Pinned tabs are global in browser-laptop, while they are per-tab in + // brave-core. To manage this transition, import all pinned tabs into the + // first imported window only. + std::vector pinnedTabs = ParsePinnedTabs(pinnedSites); + + if (!windows.empty() && !cancelled()) { + ImportedWindowState windowState; + windowState.windows = windows; + windowState.pinnedTabs = pinnedTabs; + bridge_->UpdateWindows(windowState); + } +} diff --git a/utility/importer/brave_importer.h b/utility/importer/brave_importer.h index 804076c9e364..97fe8dabc0cb 100644 --- a/utility/importer/brave_importer.h +++ b/utility/importer/brave_importer.h @@ -34,6 +34,7 @@ class BraveImporter : public ChromeImporter { void ImportHistory() override; void ImportStats(); void ImportLedger(); + void ImportWindows(); void ImportReferral(); std::unique_ptr ParseBraveStateFile( diff --git a/utility/importer/brave_importer_unittest.cc b/utility/importer/brave_importer_unittest.cc index 8a902806bd78..b0095da5c8ca 100644 --- a/utility/importer/brave_importer_unittest.cc +++ b/utility/importer/brave_importer_unittest.cc @@ -243,3 +243,7 @@ TEST_F(BraveImporterTest, ImportStats) { TEST_F(BraveImporterTest, ImportLedger) { // TODO } + +TEST_F(BraveImporterTest, ImportWindows) { + // TODO +}