-
Notifications
You must be signed in to change notification settings - Fork 888
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue 6251: Backport firefox importer fix.
Fix brave/brave-browser#6521 See https://chromium-review.googlesource.com/#/q/If2b2a4dbfacc3849cdf58e92b94c420ad126baf2
- Loading branch information
Ivan Efremov
committed
Nov 4, 2019
1 parent
b5f0013
commit d804c06
Showing
6 changed files
with
480 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,65 @@ | ||
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc | ||
index 9b05880c7b94700e2cbfdddcd8e0b95cd11f7c4e..08e519ba345854aa29dc5927b58fe6325228e55d 100644 | ||
index 9b05880c7b94700e2cbfdddcd8e0b95cd11f7c4e..f6b4919378cc72bffe1e95d261566364e3a06e4b 100644 | ||
--- a/chrome/browser/shell_integration_win.cc | ||
+++ b/chrome/browser/shell_integration_win.cc | ||
@@ -588,6 +588,14 @@ bool IsFirefoxDefaultBrowser() { | ||
app_cmd == L"FirefoxURL"; | ||
@@ -492,6 +492,15 @@ void IsPinnedToTaskbarHelper::OnIsPinnedToTaskbarResult( | ||
delete this; | ||
} | ||
|
||
+bool IsIEDefaultBrowser() { | ||
+ base::string16 app_cmd; | ||
+base::string16 GetHttpProtocolUserChoiceProgId() { | ||
+ base::string16 prog_id; | ||
+ base::win::RegKey key(HKEY_CURRENT_USER, ShellUtil::kRegVistaUrlPrefs, | ||
+ KEY_READ); | ||
+ return key.Valid() && key.ReadValue(L"Progid", &app_cmd) == ERROR_SUCCESS && | ||
+ app_cmd == L"IE.HTTP"; | ||
+ KEY_QUERY_VALUE); | ||
+ if (key.Valid()) | ||
+ key.ReadValue(L"ProgId", &prog_id); | ||
+ return prog_id; | ||
+} | ||
+ | ||
} // namespace | ||
|
||
bool SetAsDefaultBrowser() { | ||
@@ -569,23 +578,28 @@ DefaultWebClientState GetDefaultBrowser() { | ||
ShellUtil::GetChromeDefaultState()); | ||
} | ||
|
||
-// There is no reliable way to say which browser is default on a machine (each | ||
-// browser can have some of the protocols/shortcuts). So we look for only HTTP | ||
-// protocol handler. Even this handler is located at different places in | ||
-// registry on XP and Vista: | ||
-// - HKCR\http\shell\open\command (XP) | ||
-// - HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\ | ||
-// http\UserChoice (Vista) | ||
-// This method checks if Firefox is default browser by checking these | ||
-// locations and returns true if Firefox traces are found there. In case of | ||
-// error (or if Firefox is not found)it returns the default value which | ||
-// is false. | ||
+// This method checks if Firefox is default browser by checking for the default | ||
+// HTTP protocol handler. Returns false in case of error or if Firefox is not | ||
+// the user's default http protocol client. | ||
bool IsFirefoxDefaultBrowser() { | ||
- base::string16 app_cmd; | ||
- base::win::RegKey key(HKEY_CURRENT_USER, ShellUtil::kRegVistaUrlPrefs, | ||
- KEY_READ); | ||
- return key.Valid() && key.ReadValue(L"Progid", &app_cmd) == ERROR_SUCCESS && | ||
- app_cmd == L"FirefoxURL"; | ||
+ return base::StartsWith(GetHttpProtocolUserChoiceProgId(), L"FirefoxURL", | ||
+ base::CompareCase::SENSITIVE); | ||
+} | ||
+ | ||
+std::string GetFirefoxProgIdSuffix() { | ||
+ const base::string16 app_cmd = GetHttpProtocolUserChoiceProgId(); | ||
+ static constexpr base::StringPiece16 kFirefoxProgIdPrefix(L"FirefoxURL-"); | ||
+ if (base::StartsWith(app_cmd, kFirefoxProgIdPrefix, | ||
+ base::CompareCase::SENSITIVE)) { | ||
+ // Returns the id that appears after the prefix "FirefoxURL-". | ||
+ return std::string(app_cmd.begin() + kFirefoxProgIdPrefix.size(), | ||
+ app_cmd.end()); | ||
+ } | ||
+ return std::string(); | ||
+} | ||
+ | ||
+bool IsIEDefaultBrowser() { | ||
+ return GetHttpProtocolUserChoiceProgId() == L"IE.HTTP"; | ||
} | ||
|
||
DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) { | ||
return GetDefaultWebClientStateFromShellUtilDefaultState( | ||
ShellUtil::GetChromeDefaultProtocolClientState( |
137 changes: 137 additions & 0 deletions
137
patches/chrome-common-importer-firefox_importer_utils.cc.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
diff --git a/chrome/common/importer/firefox_importer_utils.cc b/chrome/common/importer/firefox_importer_utils.cc | ||
index e1f5ada77718755f5a59d78e63a14e500330e002..7360ca488a158b70c99f55c4ba170777a19d5181 100644 | ||
--- a/chrome/common/importer/firefox_importer_utils.cc | ||
+++ b/chrome/common/importer/firefox_importer_utils.cc | ||
@@ -50,51 +50,107 @@ base::FilePath GetProfilePath(const base::DictionaryValue& root, | ||
return path; | ||
} | ||
|
||
-// Checks if the named profile is the default profile. | ||
-bool IsDefaultProfile(const base::DictionaryValue& root, | ||
- const std::string& profile_name) { | ||
- std::string is_default; | ||
- root.GetStringASCII(profile_name + ".Default", &is_default); | ||
- return is_default == "1"; | ||
+// Returns a map from Firefox profiles to their corresponding installation ids. | ||
+// The keys are file system paths for Firefox profiles that are the default | ||
+// profile in their installation. The values are the registry keys for the | ||
+// corresponding installation. | ||
+std::map<std::string, std::string> GetDefaultProfilesPerInstall( | ||
+ const base::DictionaryValue& root) { | ||
+ std::map<std::string, std::string> default_profile_to_install_id; | ||
+ static constexpr base::StringPiece kInstallPrefix("Install"); | ||
+ // Find the default profiles for each Firefox installation. | ||
+ for (const auto& data : root) { | ||
+ const std::string& dict_key = data.first; | ||
+ if (base::StartsWith(dict_key, kInstallPrefix, | ||
+ base::CompareCase::SENSITIVE)) { | ||
+ std::string path; | ||
+ if (root.GetStringASCII(dict_key + ".Default", &path)) { | ||
+ default_profile_to_install_id.emplace( | ||
+ std::move(path), dict_key.substr(kInstallPrefix.size())); | ||
+ } | ||
+ } | ||
+ } | ||
+ return default_profile_to_install_id; | ||
+} | ||
+ | ||
+base::FilePath GetLegacyDefaultProfilePath( | ||
+ const base::DictionaryValue& root, | ||
+ const std::vector<std::string>& profile_names) { | ||
+ if (profile_names.empty()) | ||
+ return base::FilePath(); | ||
+ | ||
+ // When multiple profiles exist, the path to the default profile is returned. | ||
+ for (const auto& profile_name : profile_names) { | ||
+ // Checks if the named profile is the default profile using the legacy | ||
+ // format of profiles.ini (Firefox version < 67). | ||
+ std::string is_default; | ||
+ if (root.GetStringASCII(profile_name + ".Default", &is_default) && | ||
+ is_default == "1") { | ||
+ return GetProfilePath(root, profile_name); | ||
+ } | ||
+ } | ||
+ | ||
+ // If no default profile is found, the path to Profile0 will be returned. | ||
+ return GetProfilePath(root, profile_names.front()); | ||
} | ||
|
||
} // namespace | ||
|
||
-base::FilePath GetFirefoxProfilePath() { | ||
+base::FilePath GetFirefoxProfilePath(const std::string& firefox_install_id) { | ||
base::FilePath ini_file = GetProfilesINI(); | ||
std::string content; | ||
base::ReadFileToString(ini_file, &content); | ||
DictionaryValueINIParser ini_parser; | ||
ini_parser.Parse(content); | ||
- return GetFirefoxProfilePathFromDictionary(ini_parser.root()); | ||
+ return GetFirefoxProfilePathFromDictionary(ini_parser.root(), | ||
+ firefox_install_id); | ||
} | ||
|
||
base::FilePath GetFirefoxProfilePathFromDictionary( | ||
- const base::DictionaryValue& root) { | ||
- std::vector<std::string> profiles; | ||
+ const base::DictionaryValue& root, | ||
+ const std::string& firefox_install_id) { | ||
+ // List of profiles linked to a Firefox installation. This will be empty for | ||
+ // Firefox versions older than 67. | ||
+ std::map<std::string, std::string> default_profile_to_install_id = | ||
+ GetDefaultProfilesPerInstall(root); | ||
+ // First profile linked to a Firefox installation (version >= 67). | ||
+ base::Optional<std::string> first_modern_profile; | ||
+ | ||
+ // Profiles not linked to a Firefox installation (version < 67). | ||
+ std::vector<std::string> legacy_profiles; | ||
+ | ||
for (int i = 0; ; ++i) { | ||
std::string current_profile = base::StringPrintf("Profile%d", i); | ||
- if (root.HasKey(current_profile)) { | ||
- profiles.push_back(current_profile); | ||
- } else { | ||
- // Profiles are continuously numbered. So we exit when we can't | ||
+ if (!root.HasKey(current_profile)) { | ||
+ // Profiles are contiguously numbered. So we exit when we can't | ||
// find the i-th one. | ||
break; | ||
} | ||
- } | ||
|
||
- if (profiles.empty()) | ||
- return base::FilePath(); | ||
+ std::string path; | ||
+ if (!root.GetStringASCII(current_profile + ".Path", &path)) | ||
+ continue; | ||
|
||
- // When multiple profiles exist, the path to the default profile is returned, | ||
- // since the other profiles are used mostly by developers for testing. | ||
- for (std::vector<std::string>::const_iterator it = profiles.begin(); | ||
- it != profiles.end(); ++it) | ||
- if (IsDefaultProfile(root, *it)) | ||
- return GetProfilePath(root, *it); | ||
+ auto install_id_it = default_profile_to_install_id.find(path); | ||
+ if (install_id_it != default_profile_to_install_id.end()) { | ||
+ // If this installation is the default browser, use the associated | ||
+ // profile as default profile. | ||
+ if (install_id_it->second == firefox_install_id) | ||
+ return GetProfilePath(root, current_profile); | ||
+ if (!first_modern_profile) | ||
+ first_modern_profile.emplace(std::move(current_profile)); | ||
+ } else { | ||
+ // If no Firefox installation found in profiles.ini, legacy profiles | ||
+ // (Firefox version < 67) are being used. | ||
+ legacy_profiles.push_back(std::move(current_profile)); | ||
+ } | ||
+ } | ||
|
||
- // If no default profile is found, the path to Profile0 will be returned. | ||
- return GetProfilePath(root, profiles.front()); | ||
+ // Take the first install found as the default install. | ||
+ if (first_modern_profile) | ||
+ return GetProfilePath(root, *first_modern_profile); | ||
+ | ||
+ return GetLegacyDefaultProfilePath(root, legacy_profiles); | ||
} | ||
|
||
#if defined(OS_MACOSX) |
25 changes: 25 additions & 0 deletions
25
patches/chrome-common-importer-firefox_importer_utils.h.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
diff --git a/chrome/common/importer/firefox_importer_utils.h b/chrome/common/importer/firefox_importer_utils.h | ||
index ec57c17927173691d98db394d726da41d1f43475..e9feec4eae2b73cea2b1c722095b4c121968aced 100644 | ||
--- a/chrome/common/importer/firefox_importer_utils.h | ||
+++ b/chrome/common/importer/firefox_importer_utils.h | ||
@@ -38,13 +38,17 @@ base::FilePath GetFirefoxInstallPathFromRegistry(); | ||
base::FilePath GetFirefoxDylibPath(); | ||
#endif // OS_MACOSX | ||
|
||
-// Returns the path to the Firefox profile. | ||
-base::FilePath GetFirefoxProfilePath(); | ||
+// Returns the path to the default profile of the Firefox installation with id | ||
+// |firefox_install_id|. | ||
+base::FilePath GetFirefoxProfilePath(const std::string& firefox_install_id); | ||
|
||
// Returns the path to the Firefox profile, using a custom dictionary. | ||
+// If |firefox_install_id| is not empty returns the default profile associated | ||
+// with that id. | ||
// Exposed for testing. | ||
base::FilePath GetFirefoxProfilePathFromDictionary( | ||
- const base::DictionaryValue& root); | ||
+ const base::DictionaryValue& root, | ||
+ const std::string& firefox_install_id); | ||
|
||
// Detects version of Firefox and installation path for the given Firefox | ||
// profile. |
Oops, something went wrong.