Commit dece487a authored by thomasanderson's avatar thomasanderson Committed by Commit bot

xdg-settings: add secondary check in GetIsDefaultWebClient

This CL fixes an issue where Chrome would display a banner saying that it
was not the default browser when it actually was.

The cause of this was 'xdg-settings check default-web-browser
google-chrome.desktop' returning 'no' when Chrome might have been the
default (see further explanation in the CL comments).

BUG=578888
R=thestig@chromium.org

Review-Url: https://codereview.chromium.org/2737283002
Cr-Commit-Position: refs/heads/master@{#456224}
parent 449ca301
...@@ -164,27 +164,26 @@ bool SetDefaultWebClient(const std::string& protocol) { ...@@ -164,27 +164,26 @@ bool SetDefaultWebClient(const std::string& protocol) {
#endif #endif
} }
// If |protocol| is empty this function checks if Chrome is the default browser, #if !defined(OS_CHROMEOS)
// otherwise it checks if Chrome is the default handler application for // If |check| is true, returns the output of "xdg-settings check {property}
// |protocol|. // *.desktop", otherwise returns the output of "xdg-settings get {property}",
DefaultWebClientState GetIsDefaultWebClient(const std::string& protocol) { // where property is "default-web-browser" if |protocol| is empty or
#if defined(OS_CHROMEOS) // "default-url-scheme-handler |protocol|" otherwise. Returns "" if
return UNKNOWN_DEFAULT; // xdg-settings fails for any reason.
#else std::string GetXdgSettingsOutput(bool check,
base::ThreadRestrictions::AssertIOAllowed(); const std::string& protocol,
base::Environment* env) {
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::vector<std::string> argv; std::vector<std::string> argv;
argv.push_back(kXdgSettings); argv.push_back(kXdgSettings);
argv.push_back("check"); argv.push_back(check ? "check" : "get");
if (protocol.empty()) { if (protocol.empty()) {
argv.push_back(kXdgSettingsDefaultBrowser); argv.push_back(kXdgSettingsDefaultBrowser);
} else { } else {
argv.push_back(kXdgSettingsDefaultSchemeHandler); argv.push_back(kXdgSettingsDefaultSchemeHandler);
argv.push_back(protocol); argv.push_back(protocol);
} }
argv.push_back(shell_integration_linux::GetDesktopName(env.get())); if (check)
argv.push_back(shell_integration_linux::GetDesktopName(env));
std::string reply; std::string reply;
int success_code; int success_code;
...@@ -197,15 +196,47 @@ DefaultWebClientState GetIsDefaultWebClient(const std::string& protocol) { ...@@ -197,15 +196,47 @@ DefaultWebClientState GetIsDefaultWebClient(const std::string& protocol) {
} }
} }
if (!ran_ok || success_code != EXIT_SUCCESS) { if (!ran_ok || success_code != EXIT_SUCCESS)
// xdg-settings failed: we can't determine or set the default browser. return std::string();
return UNKNOWN_DEFAULT;
return reply;
}
#endif
// If |protocol| is empty this function checks if Chrome is the default browser,
// otherwise it checks if Chrome is the default handler application for
// |protocol|.
DefaultWebClientState GetDefaultWebClient(const std::string& protocol) {
#if defined(OS_CHROMEOS)
return UNKNOWN_DEFAULT;
#else
base::ThreadRestrictions::AssertIOAllowed();
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string xdg_is_default = GetXdgSettingsOutput(true, protocol, env.get());
if (base::StartsWith(xdg_is_default, "yes", base::CompareCase::SENSITIVE)) {
return IS_DEFAULT;
}
if (base::StartsWith(xdg_is_default, "no", base::CompareCase::SENSITIVE)) {
// An output of "no" does not necessarily mean Chrom[e,ium] is not the
// default. According to the xdg-settings man page, this can happen when
// "only some of the underlying settings actually reflect that value". Don't
// return NOT_DEFAULT unless we're sure, or else an annoying "Chrome is not
// your default browser" banner will appear on every launch
// (https://crbug.com/578888).
if (base::StartsWith(GetXdgSettingsOutput(false, protocol, env.get()),
shell_integration_linux::GetDesktopName(env.get()),
base::CompareCase::SENSITIVE)) {
// This is the odd case where 'xdg-settings check' said that Chrome wasn't
// the default, but 'xdg-settings get' returned Chrome as the default.
return UNKNOWN_DEFAULT;
}
// xdg-settings says the default is non-Chrome, and is self-consistent.
return NOT_DEFAULT;
} }
// Allow any reply that starts with "yes". // xdg-settings failed: we can't determine or set the default browser.
return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE) return UNKNOWN_DEFAULT;
? IS_DEFAULT
: NOT_DEFAULT;
#endif #endif
} }
...@@ -243,7 +274,7 @@ base::string16 GetApplicationNameForProtocol(const GURL& url) { ...@@ -243,7 +274,7 @@ base::string16 GetApplicationNameForProtocol(const GURL& url) {
} }
DefaultWebClientState GetDefaultBrowser() { DefaultWebClientState GetDefaultBrowser() {
return GetIsDefaultWebClient(std::string()); return GetDefaultWebClient(std::string());
} }
bool IsFirefoxDefaultBrowser() { bool IsFirefoxDefaultBrowser() {
...@@ -259,7 +290,7 @@ bool IsFirefoxDefaultBrowser() { ...@@ -259,7 +290,7 @@ bool IsFirefoxDefaultBrowser() {
} }
DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) { DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) {
return GetIsDefaultWebClient(protocol); return GetDefaultWebClient(protocol);
} }
} // namespace shell_integration } // namespace shell_integration
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment