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 https://mozilla.org/MPL/2.0/.
Copyright (c) 2019, The Brave Authors
Copyright (c) 2025, The Helium Authors
Alternatively, the contents of this file may be used under the terms
of the GNU General Public License Version 3, as described below:
Copyright (C) 2025 The Helium Authors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
--- a/chrome/browser/importer/importer_list.cc
+++ b/chrome/browser/importer/importer_list.cc
@@ -27,6 +27,8 @@
#include "chrome/common/importer/edge_importer_utils_win.h"
#endif
+#include "chrome/browser/importer/chrome_importer_list.cc"
+
namespace {
#if BUILDFLAG(IS_WIN)
@@ -171,20 +173,30 @@ std::vector
+
--- a/components/user_data_importer/common/importer_data_types.h
+++ b/components/user_data_importer/common/importer_data_types.h
@@ -29,7 +29,8 @@ 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.
+ EXTENSIONS = 1 << 7,
+ ALL = (1 << 8) - 1 // All the bits should be 1, hence the -1.
};
// Information about a profile needed by an importer to do import work.
@@ -111,6 +112,7 @@ enum VisitSource {
VISIT_SOURCE_FIREFOX_IMPORTED = 1,
VISIT_SOURCE_IE_IMPORTED = 2,
VISIT_SOURCE_SAFARI_IMPORTED = 3,
+ VISIT_SOURCE_CHROME_IMPORTED = 4,
};
} // namespace user_data_importer
--- a/chrome/common/importer/profile_import_process_param_traits_macros.h
+++ b/chrome/common/importer/profile_import_process_param_traits_macros.h
@@ -23,11 +23,11 @@
#if BUILDFLAG(IS_WIN)
IPC_ENUM_TRAITS_MIN_MAX_VALUE(user_data_importer::ImporterType,
user_data_importer::TYPE_UNKNOWN,
- user_data_importer::TYPE_EDGE)
+ user_data_importer::TYPE_PERPLEXITY_COMET)
#else
IPC_ENUM_TRAITS_MIN_MAX_VALUE(user_data_importer::ImporterType,
user_data_importer::TYPE_UNKNOWN,
- user_data_importer::TYPE_BOOKMARKS_FILE)
+ user_data_importer::TYPE_PERPLEXITY_COMET)
#endif
IPC_ENUM_TRAITS_MIN_MAX_VALUE(user_data_importer::ImportItem,
--- a/chrome/browser/ui/webui/settings/import_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/import_data_handler.cc
@@ -150,6 +150,9 @@ void ImportDataHandler::HandleImportData
if (*type_dict.FindBool(prefs::kImportDialogSearchEngine)) {
selected_items |= user_data_importer::SEARCH_ENGINES;
}
+ if (*type_dict.FindBool(prefs::kImportDialogExtensions)) {
+ selected_items |= user_data_importer::EXTENSIONS;
+ }
const user_data_importer::SourceProfile& source_profile =
importer_list_->GetSourceProfileAt(browser_index);
@@ -231,6 +234,8 @@ void ImportDataHandler::SendBrowserProfi
browser_profile.Set(
"autofillFormData",
(browser_services & user_data_importer::AUTOFILL_FORM_DATA) != 0);
+ browser_profile.Set("extensions",
+ (browser_services & user_data_importer::EXTENSIONS) != 0);
browser_profiles.Append(std::move(browser_profile));
}
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -3266,6 +3266,9 @@ inline constexpr char kDataUrlInWebWorke
inline constexpr char kSharedWorkerExtendedLifetimeEnabled[] =
"worker.shared_worker_extended_lifetime_enabled";
+inline constexpr char kImportDialogExtensions[] =
+ "import_dialog_extensions";
+
// Boolean indicating whether clearing window.name when the navigation is
// top-level, cross-site and swaps BrowsingContextGroup is allowed or not.
inline constexpr char kClearWindowNameForNewBrowsingContextGroup[] =
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -1236,6 +1236,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil
settings_api::PrefType::kBoolean;
(*s_allowlist)[::prefs::kImportDialogSearchEngine] =
settings_api::PrefType::kBoolean;
+ (*s_allowlist)[::prefs::kImportDialogExtensions] =
+ settings_api::PrefType::kBoolean;
#endif // BUILDFLAG(IS_CHROMEOS)
// Supervised Users. This setting is queried in our Tast tests (b/241943380).
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -64,6 +64,7 @@
#include "chrome/browser/ui/webui/settings/about_handler.h"
#include "chrome/browser/ui/webui/settings/accessibility_main_handler.h"
#include "chrome/browser/ui/webui/settings/appearance_handler.h"
+#include "chrome/browser/ui/webui/settings/brave_import_data_handler.h"
#include "chrome/browser/ui/webui/settings/browser_lifetime_handler.h"
#include "chrome/browser/ui/webui/settings/device_tab_visibility_handler.h"
#include "chrome/browser/ui/webui/settings/dictation_handler.h"
@@ -233,6 +234,7 @@ void SettingsUI::RegisterProfilePrefs(
registry->RegisterBooleanPref(prefs::kImportDialogHistory, true);
registry->RegisterBooleanPref(prefs::kImportDialogSavedPasswords, true);
registry->RegisterBooleanPref(prefs::kImportDialogSearchEngine, true);
+ registry->RegisterBooleanPref(prefs::kImportDialogExtensions, true);
registry->RegisterDictionaryPref(prefs::kDeviceTabVisibilityHiddenSessions);
}
@@ -268,7 +270,7 @@ SettingsUI::SettingsUI(content::WebUI* w
AddSettingsPageUIHandler(std::make_unique(profile));
AddSettingsPageUIHandler(std::make_unique());
AddSettingsPageUIHandler(std::make_unique(profile));
- AddSettingsPageUIHandler(std::make_unique());
+ AddSettingsPageUIHandler(std::make_unique());
AddSettingsPageUIHandler(std::make_unique());
#if BUILDFLAG(IS_WIN)
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1253,6 +1253,8 @@ void AddImportDataStrings(content::WebUI
{"importHistory", IDS_SETTINGS_IMPORT_HISTORY_CHECKBOX},
{"importFavorites", IDS_SETTINGS_IMPORT_FAVORITES_CHECKBOX},
{"importPasswords", IDS_SETTINGS_IMPORT_PASSWORDS_CHECKBOX},
+ // abusing some strings here so _we_ don't have to localize them
+ {"importExtensions", IDS_EXTENSIONS_TOOLBAR_TITLE},
{"importSearch", IDS_SETTINGS_IMPORT_SEARCH_ENGINES_CHECKBOX},
{"importAutofillFormData",
IDS_SETTINGS_IMPORT_AUTOFILL_FORM_DATA_CHECKBOX},
--- a/chrome/browser/resources/settings/people_page/import_data_dialog.html.ts
+++ b/chrome/browser/resources/settings/people_page/import_data_dialog.html.ts
@@ -70,6 +70,11 @@ export function getHtml(this: SettingsIm
pref-key="import_dialog_autofill_form_data"
label="$i18n{importAutofillFormData}" no-set-pref>
+
+
--- a/chrome/browser/resources/settings/people_page/import_data_browser_proxy.ts
+++ b/chrome/browser/resources/settings/people_page/import_data_browser_proxy.ts
@@ -19,6 +19,7 @@ export interface BrowserProfile {
passwords: boolean;
search: boolean;
autofillFormData: boolean;
+ extensions: boolean;
}
/**
--- a/chrome/browser/resources/settings/people_page/import_data_dialog.ts
+++ b/chrome/browser/resources/settings/people_page/import_data_dialog.ts
@@ -78,6 +78,7 @@ export class SettingsImportDataDialogEle
passwords: false,
search: false,
autofillFormData: false,
+ extensions: false,
};
protected accessor noImportDataTypeSelected_: boolean = false;
protected accessor importStatus_: ImportDataStatus = ImportDataStatus.INITIAL;
--- a/chrome/browser/ui/webui/settings/BUILD.gn
+++ b/chrome/browser/ui/webui/settings/BUILD.gn
@@ -13,6 +13,8 @@ source_set("settings") {
"about_handler.h",
"accessibility_main_handler.h",
"appearance_handler.h",
+ "brave_import_data_handler.h",
+ "brave_importer_observer.h",
"browser_lifetime_handler.h",
"captions_handler.h",
"custom_home_pages_table_model.h",
@@ -127,6 +129,7 @@ source_set("settings") {
if (is_mac) {
sources += [ "mac_system_settings_handler.h" ]
+ sources += [ "brave_full_disk_access_confirm_dialog_delegate.h" ]
}
if (is_chromeos) {
@@ -144,6 +147,8 @@ source_set("impl") {
"about_handler.cc",
"accessibility_main_handler.cc",
"appearance_handler.cc",
+ "brave_import_data_handler.cc",
+ "brave_importer_observer.cc",
"browser_lifetime_handler.cc",
"captions_handler.cc",
"custom_home_pages_table_model.cc",
@@ -375,6 +380,7 @@ source_set("impl") {
sources += [
"mac_system_settings_handler.cc",
"settings_utils_mac.mm",
+ "brave_full_disk_access_confirm_dialog_delegate_mac.mm",
]
}
--- a/chrome/browser/ui/webui/settings/import_data_handler.h
+++ b/chrome/browser/ui/webui/settings/import_data_handler.h
@@ -36,9 +36,9 @@ class ImportDataHandler : public Setting
void RegisterMessages() override;
void OnJavascriptAllowed() override {}
void OnJavascriptDisallowed() override;
-
+ friend class BraveImportDataHandler;
private:
- void StartImport(const user_data_importer::SourceProfile& source_profile,
+ virtual void StartImport(const user_data_importer::SourceProfile& source_profile,
uint16_t imported_items);
// Handler for the "importData" message. First argument is the selected
--- a/chrome/browser/importer/BUILD.gn
+++ b/chrome/browser/importer/BUILD.gn
@@ -6,6 +6,10 @@ assert(is_win || is_mac || is_linux || i
source_set("importer") {
sources = [
+ "brave_external_process_importer_client.h",
+ "brave_external_process_importer_host.h",
+ "brave_in_process_importer_bridge.h",
+ "extensions_import_helpers.h",
"external_process_importer_client.h",
"external_process_importer_host.h",
"firefox_profile_lock.h",
@@ -35,6 +39,10 @@ source_set("importer") {
source_set("impl") {
sources = [
+ "brave_external_process_importer_client.cc",
+ "brave_external_process_importer_host.cc",
+ "brave_in_process_importer_bridge.cc",
+ "extensions_import_helpers.cc",
"external_process_importer_client.cc",
"external_process_importer_host.cc",
"firefox_profile_lock.cc",
--- a/chrome/browser/importer/external_process_importer_host.h
+++ b/chrome/browser/importer/external_process_importer_host.h
@@ -79,8 +79,13 @@ class ExternalProcessImporterHost
void NotifyImportStarted();
void NotifyImportItemStarted(user_data_importer::ImportItem item);
void NotifyImportItemEnded(user_data_importer::ImportItem item);
- void NotifyImportEnded();
+ void virtual NotifyImportEnded();
+ friend class BraveExternalProcessImporterHost;
+ void set_parent_view(gfx::NativeView parent_view) {
+ parent_view_ = parent_view;
+ }
+ gfx::NativeView parent_view_ = gfx::NativeView();
private:
// ExternalProcessImporterHost deletes itself in OnImportEnded().
~ExternalProcessImporterHost() override;
--- a/components/history/core/browser/history_types.h
+++ b/components/history/core/browser/history_types.h
@@ -56,6 +56,8 @@ enum VisitSource {
SOURCE_SAFARI_IMPORTED = 5,
SOURCE_ACTOR = 6, // Added by the GLIC actor.
SOURCE_OS_MIGRATION_IMPORTED = 7,
+ SOURCE_CHROME_IMPORTED = 8,
+ SOURCE_BRAVE_IMPORTED = 9,
};
// Corresponds to the "id" column of the "visited_links" SQL table.
--- a/components/history/core/browser/visit_database.cc
+++ b/components/history/core/browser/visit_database.cc
@@ -123,6 +123,8 @@ VisitSource VisitSourceFromInt(int value
case SOURCE_SAFARI_IMPORTED:
case SOURCE_ACTOR:
case SOURCE_OS_MIGRATION_IMPORTED:
+ case SOURCE_CHROME_IMPORTED:
+ case SOURCE_BRAVE_IMPORTED:
return converted;
}
// In cases of database corruption, SOURCE_BROWSED is a safe default value.
--- a/chrome/browser/importer/in_process_importer_bridge.cc
+++ b/chrome/browser/importer/in_process_importer_bridge.cc
@@ -53,6 +53,8 @@ history::VisitSource ConvertImporterVisi
return history::SOURCE_IE_IMPORTED;
case user_data_importer::VISIT_SOURCE_SAFARI_IMPORTED:
return history::SOURCE_SAFARI_IMPORTED;
+ case user_data_importer::VISIT_SOURCE_CHROME_IMPORTED:
+ return history::SOURCE_CHROME_IMPORTED;
}
NOTREACHED();
}
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -96,6 +96,12 @@ static_library("utility") {
sources += [
"importer/bookmarks_file_importer.cc",
"importer/bookmarks_file_importer.h",
+ "importer/brave_external_process_importer_bridge.cc",
+ "importer/brave_external_process_importer_bridge.h",
+ "importer/brave_profile_import_impl.cc",
+ "importer/brave_profile_import_impl.h",
+ "importer/chrome_importer.cc",
+ "importer/chrome_importer.h",
"importer/external_process_importer_bridge.cc",
"importer/external_process_importer_bridge.h",
"importer/importer.cc",
--- a/chrome/utility/services.cc
+++ b/chrome/utility/services.cc
@@ -64,8 +64,10 @@
#endif // BUILDFLAG(IS_LINUX)
#if !BUILDFLAG(IS_ANDROID)
+#include "chrome/common/importer/chrome_profile_import.mojom.h"
#include "chrome/common/importer/profile_import.mojom.h"
#include "chrome/services/reading_mode_metrics/reading_mode_metrics_service.h"
+#include "chrome/utility/importer/brave_profile_import_impl.h"
#include "chrome/utility/importer/profile_import_impl.h"
#include "components/mirroring/service/mirroring_service.h"
#include "services/proxy_resolver/proxy_resolver_factory_impl.h" // nogncheck
@@ -156,6 +158,13 @@ static_assert(BUILDFLAG(ENABLE_PRINTING)
namespace {
+#if !BUILDFLAG(IS_ANDROID)
+auto RunBraveProfileImporter(
+ mojo::PendingReceiver receiver) {
+ return std::make_unique(std::move(receiver));
+}
+#endif
+
auto RunFilePatcher(mojo::PendingReceiver receiver) {
return std::make_unique(std::move(receiver));
}
@@ -503,6 +512,7 @@ void RegisterMainThreadServices(mojo::Se
#endif // BUILDFLAG(IS_ANDROID)
#if !BUILDFLAG(IS_ANDROID)
+ services.Add(RunBraveProfileImporter);
services.Add(RunProfileImporter);
services.Add(RunMirroringService);
services.Add(RunReadingModeMetricsService);
--- a/chrome/utility/importer/external_process_importer_bridge.h
+++ b/chrome/utility/importer/external_process_importer_bridge.h
@@ -72,7 +72,7 @@ class ExternalProcessImporterBridge : pu
std::u16string GetLocalizedString(int message_id) override;
// End ImporterBridge implementation.
-
+ friend class BraveExternalProcessImporterBridge;
private:
~ExternalProcessImporterBridge() override;
--- a/chrome/browser/importer/external_process_importer_host.cc
+++ b/chrome/browser/importer/external_process_importer_host.cc
@@ -8,6 +8,8 @@
#include "base/functional/bind.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/importer/brave_external_process_importer_client.h"
+#include "chrome/browser/importer/brave_in_process_importer_bridge.h"
#include "chrome/browser/importer/external_process_importer_client.h"
#include "chrome/browser/importer/firefox_profile_lock.h"
#include "chrome/browser/importer/importer_lock_dialog.h"
@@ -102,10 +104,10 @@ void ExternalProcessImporterHost::Launch
// bridge lives in the external process (see ProfileImportThread).
// The ExternalProcessImporterClient created in the next line owns the bridge,
// and will delete it.
- InProcessImporterBridge* bridge =
- new InProcessImporterBridge(writer_.get(),
+ BraveInProcessImporterBridge* bridge =
+ new BraveInProcessImporterBridge(writer_.get(),
weak_ptr_factory_.GetWeakPtr());
- client_ = new ExternalProcessImporterClient(
+ client_ = new BraveExternalProcessImporterClient(
weak_ptr_factory_.GetWeakPtr(), source_profile_, items_, bridge);
client_->Start();
}
--- a/chrome/browser/importer/in_process_importer_bridge.h
+++ b/chrome/browser/importer/in_process_importer_bridge.h
@@ -59,7 +59,7 @@ class InProcessImporterBridge : public I
std::u16string GetLocalizedString(int message_id) override;
// End ImporterBridge implementation.
-
+ friend class BraveInProcessImporterBridge;
private:
~InProcessImporterBridge() override;
--- a/chrome/browser/importer/importer_uma.cc
+++ b/chrome/browser/importer/importer_uma.cc
@@ -59,6 +59,9 @@ void LogImporterUseToMetrics(const std::
case user_data_importer::TYPE_BOOKMARKS_FILE:
metrics_type = IMPORTER_METRICS_BOOKMARKS_FILE;
break;
+ default:
+ metrics_type = IMPORTER_METRICS_UNKNOWN;
+ break;
}
// Note: This leaks memory, which is the expected behavior as the factory
--- a/chrome/browser/importer/external_process_importer_client.h
+++ b/chrome/browser/importer/external_process_importer_client.h
@@ -48,10 +48,10 @@ class ExternalProcessImporterClient
const ExternalProcessImporterClient&) = delete;
// Launches the task to start the external process.
- void Start();
+ virtual void Start();
// Called by the ExternalProcessImporterHost on import cancel.
- void Cancel();
+ virtual void Cancel();
// chrome::mojom::ProfileImportObserver:
void OnImportStart() override;
@@ -82,6 +82,8 @@ class ExternalProcessImporterClient
const std::vector&
autofill_form_data_entry_group) override;
+ friend class BraveExternalProcessImporterClient;
+
protected:
~ExternalProcessImporterClient() override;
@@ -97,7 +99,7 @@ class ExternalProcessImporterClient
// The Mojo connections need to be torn down on the same thread that created
// them, but the destructor is not guaranteed to be run on that thread so we
// tear down the connections explicitly.
- void CloseMojoHandles();
+ virtual void CloseMojoHandles();
// These variables store data being collected from the importer until the
// entire group has been collected and is ready to be written to the profile.
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -11833,6 +11833,15 @@ Check your passwords anytime in
+
+ Imported from $1Chrome
+
+
+ Import profile still in use
+
+
+ To continue importing data, first close the browser you're importing from.
+
Mozilla Firefox
--- a/chrome/browser/importer/importer_lock_dialog.h
+++ b/chrome/browser/importer/importer_lock_dialog.h
@@ -21,6 +21,11 @@ void ShowImportLockDialog(gfx::NativeWin
base::OnceCallback callback,
int importer_lock_title_id = IDS_IMPORTER_LOCK_TITLE,
int importer_lock_text_id = IDS_IMPORTER_LOCK_TEXT);
+void ShowImportLockDialog(gfx::NativeView parent_view,
+ gfx::NativeWindow parent,
+ base::OnceCallback callback,
+ int importer_lock_title_id = IDS_IMPORTER_LOCK_TITLE,
+ int importer_lock_text_id = IDS_IMPORTER_LOCK_TEXT);
} // namespace importer
--- a/chrome/browser/ui/views/importer/import_lock_dialog_view.cc
+++ b/chrome/browser/ui/views/importer/import_lock_dialog_view.cc
@@ -28,8 +28,36 @@ void ShowImportLockDialog(gfx::NativeWin
importer_lock_title_id, importer_lock_text_id);
}
+void ShowImportLockDialog(gfx::NativeView parent_view,
+ gfx::NativeWindow parent,
+ base::OnceCallback callback,
+ int importer_lock_title_id,
+ int importer_lock_text_id) {
+ ImportLockDialogView::Show(parent_view, parent, std::move(callback),
+ importer_lock_title_id, importer_lock_text_id);
+}
+
} // namespace importer
+
+// static
+void ImportLockDialogView::Show(gfx::NativeView parent_view,
+ gfx::NativeWindow parent,
+ base::OnceCallback callback,
+ int importer_lock_title_id,
+ int importer_lock_text_id) {
+ views::DialogDelegate::CreateDialogWidget(
+ new ImportLockDialogView(std::move(callback), importer_lock_title_id,
+ importer_lock_text_id),
+ parent, parent_view)
+ ->Show();
+ base::RecordAction(UserMetricsAction("ImportLockDialogView_Shown"));
+}
+
+ui::mojom::ModalType ImportLockDialogView::GetModalType() const {
+ return ui::mojom::ModalType::kChild;
+}
+
// static
void ImportLockDialogView::Show(gfx::NativeWindow parent,
base::OnceCallback callback,
--- a/chrome/browser/ui/views/importer/import_lock_dialog_view.h
+++ b/chrome/browser/ui/views/importer/import_lock_dialog_view.h
@@ -23,6 +23,12 @@ class ImportLockDialogView : public view
base::OnceCallback callback,
int importer_lock_title_id = IDS_IMPORTER_LOCK_TITLE,
int importer_lock_text_id = IDS_IMPORTER_LOCK_TEXT);
+ static void Show(gfx::NativeView parent_view,
+ gfx::NativeWindow parent,
+ base::OnceCallback callback,
+ int importer_lock_title_id = IDS_IMPORTER_LOCK_TITLE,
+ int importer_lock_text_id = IDS_IMPORTER_LOCK_TEXT);
+ ui::mojom::ModalType GetModalType() const override;
private:
ImportLockDialogView(base::OnceCallback callback,