summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.cc3
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc2
-rw-r--r--chrome/browser/external_protocol/external_protocol_handler_unittest.cc2
-rw-r--r--chrome/browser/first_run/first_run.cc5
-rw-r--r--chrome/browser/shell_integration.cc30
-rw-r--r--chrome/browser/shell_integration.h35
-rw-r--r--chrome/browser/shell_integration_android.cc5
-rw-r--r--chrome/browser/shell_integration_linux.cc5
-rw-r--r--chrome/browser/shell_integration_mac.mm15
-rw-r--r--chrome/browser/shell_integration_win.cc28
-rw-r--r--chrome/browser/ui/cocoa/first_run_dialog.mm3
-rw-r--r--chrome/browser/ui/startup/default_browser_prompt.cc51
-rw-r--r--chrome/browser/ui/webui/options2/browser_options_handler2.cc7
-rw-r--r--chrome/browser/ui/webui/options2/browser_options_handler2.h1
-rw-r--r--chrome/installer/util/shell_util.cc55
-rw-r--r--chrome/installer/util/shell_util.h9
16 files changed, 202 insertions, 54 deletions
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index 0300e6d..5a6dfae 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -39,7 +39,8 @@ bool ShouldRemoveHandlersNotInOS() {
// difference (http://crbug.com/88255).
return false;
#else
- return ShellIntegration::CanSetAsDefaultProtocolClient();
+ return ShellIntegration::CanSetAsDefaultProtocolClient() !=
+ ShellIntegration::SET_DEFAULT_NOT_ALLOWED;
#endif
}
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index 83161e6..570b21d 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -126,7 +126,7 @@ class FakeProtocolClientWorker
}
}
- virtual void SetAsDefault() {}
+ virtual void SetAsDefault(bool interactive_permitted) {}
private:
bool force_failure_;
diff --git a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
index 22bf9cb..eba808d 100644
--- a/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
+++ b/chrome/browser/external_protocol/external_protocol_handler_unittest.cc
@@ -27,7 +27,7 @@ class FakeExternalProtocolHandlerWorker
return os_state_;
}
- virtual void SetAsDefault() {}
+ virtual void SetAsDefault(bool interactive_permitted) {}
ShellIntegration::DefaultWebClientState os_state_;
};
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc
index f831c6b..91ebc1a 100644
--- a/chrome/browser/first_run/first_run.cc
+++ b/chrome/browser/first_run/first_run.cc
@@ -375,8 +375,11 @@ void AutoImportPlatformCommon(
ShowFirstRunDialog(profile);
}
- if (make_chrome_default)
+ if (make_chrome_default &&
+ ShellIntegration::CanSetAsDefaultBrowser() ==
+ ShellIntegration::SET_DEFAULT_UNATTENDED) {
ShellIntegration::SetAsDefaultBrowser();
+ }
// Display the first run bubble if there is a default search provider.
TemplateURLService* template_url =
diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc
index 6748679..7375443 100644
--- a/chrome/browser/shell_integration.cc
+++ b/chrome/browser/shell_integration.cc
@@ -18,7 +18,8 @@
using content::BrowserThread;
-bool ShellIntegration::CanSetAsDefaultProtocolClient() {
+ShellIntegration::DefaultWebClientSetPermission
+ ShellIntegration::CanSetAsDefaultProtocolClient() {
// Allowed as long as the browser can become the operating system default
// browser.
return CanSetAsDefaultBrowser();
@@ -92,6 +93,13 @@ CommandLine ShellIntegration::CommandLineArgsForLauncher(
return new_cmd_line;
}
+#if !defined(OS_WIN)
+// static
+bool ShellIntegration::SetAsDefaultBrowserInteractive() {
+ return false;
+}
+#endif
+
///////////////////////////////////////////////////////////////////////////////
// ShellIntegration::DefaultWebClientWorker
//
@@ -154,7 +162,7 @@ void ShellIntegration::DefaultWebClientWorker::CompleteCheckIsDefault(
void ShellIntegration::DefaultWebClientWorker::ExecuteSetAsDefault() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- SetAsDefault();
+ SetAsDefault(observer_ && observer_->IsInteractiveSetDefaultPermitted());
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
@@ -203,8 +211,19 @@ ShellIntegration::DefaultBrowserWorker::CheckIsDefault() {
return ShellIntegration::IsDefaultBrowser();
}
-void ShellIntegration::DefaultBrowserWorker::SetAsDefault() {
- ShellIntegration::SetAsDefaultBrowser();
+void ShellIntegration::DefaultBrowserWorker::SetAsDefault(
+ bool interactive_permitted) {
+ switch (ShellIntegration::CanSetAsDefaultBrowser()) {
+ case ShellIntegration::SET_DEFAULT_UNATTENDED:
+ ShellIntegration::SetAsDefaultBrowser();
+ break;
+ case ShellIntegration::SET_DEFAULT_INTERACTIVE:
+ if (interactive_permitted)
+ ShellIntegration::SetAsDefaultBrowserInteractive();
+ break;
+ default:
+ NOTREACHED();
+ }
}
///////////////////////////////////////////////////////////////////////////////
@@ -225,6 +244,7 @@ ShellIntegration::DefaultProtocolClientWorker::CheckIsDefault() {
return ShellIntegration::IsDefaultProtocolClient(protocol_);
}
-void ShellIntegration::DefaultProtocolClientWorker::SetAsDefault() {
+void ShellIntegration::DefaultProtocolClientWorker::SetAsDefault(
+ bool interactive_permitted) {
ShellIntegration::SetAsDefaultProtocolClient(protocol_);
}
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h
index 2c1ae79..eb7d716 100644
--- a/chrome/browser/shell_integration.h
+++ b/chrome/browser/shell_integration.h
@@ -23,16 +23,32 @@ class ShellIntegration {
// false if this operation fails.
static bool SetAsDefaultBrowser();
+ // Initiates an OS shell flow which (if followed by the user) should set
+ // Chrome as the default browser. Returns false if the flow cannot be
+ // initialized, if it is not supported (introduced for Windows 8) or if the
+ // user cancels the operation. This is a blocking call and requires a FILE
+ // thread.
+ static bool SetAsDefaultBrowserInteractive();
+
// Sets Chrome as the default client application for the given protocol
// (only for the current user). Returns false if this operation fails.
static bool SetAsDefaultProtocolClient(const std::string& protocol);
- // Returns true if the running browser can be set as the default browser.
- static bool CanSetAsDefaultBrowser();
+ // In Windows 8 a browser can be made default-in-metro only in an interactive
+ // flow. We will distinguish between two types of permissions here to avoid
+ // forcing the user into UI interaction when this should not be done.
+ enum DefaultWebClientSetPermission {
+ SET_DEFAULT_NOT_ALLOWED = 0,
+ SET_DEFAULT_UNATTENDED,
+ SET_DEFAULT_INTERACTIVE,
+ };
+
+ // Returns requirements for making the running browser the user's default.
+ static DefaultWebClientSetPermission CanSetAsDefaultBrowser();
- // Returns true if the running browser can be set as the default client
- // application for specific protocols.
- static bool CanSetAsDefaultProtocolClient();
+ // Returns requirements for making the running browser the user's default
+ // client application for specific protocols.
+ static DefaultWebClientSetPermission CanSetAsDefaultProtocolClient();
// On Linux, it may not be possible to determine or set the default browser
// on some desktop environments or configurations. So, we use this enum and
@@ -150,6 +166,9 @@ class ShellIntegration {
// Observer classes that return true to OwnedByWorker are automatically
// freed by the worker when they are no longer needed.
virtual bool IsOwnedByWorker() { return false; }
+ // An observer can permit or decline set-as-default operation if it
+ // requires triggering user interaction.
+ virtual bool IsInteractiveSetDefaultPermitted() { return false; }
};
// Helper objects that handle checking if Chrome is the default browser
@@ -185,7 +204,7 @@ class ShellIntegration {
virtual DefaultWebClientState CheckIsDefault() = 0;
// Function that sets Chrome as the default web client.
- virtual void SetAsDefault() = 0;
+ virtual void SetAsDefault(bool interactive_permitted) = 0;
// Function that handles performing the check on the file thread. This
// function is posted as a task onto the file thread, where it performs
@@ -234,7 +253,7 @@ class ShellIntegration {
virtual DefaultWebClientState CheckIsDefault() OVERRIDE;
// Set Chrome as the default browser.
- virtual void SetAsDefault() OVERRIDE;
+ virtual void SetAsDefault(bool interactive_permitted) OVERRIDE;
DISALLOW_COPY_AND_ASSIGN(DefaultBrowserWorker);
};
@@ -258,7 +277,7 @@ class ShellIntegration {
virtual DefaultWebClientState CheckIsDefault() OVERRIDE;
// Set Chrome as the default handler for this protocol.
- virtual void SetAsDefault() OVERRIDE;
+ virtual void SetAsDefault(bool interactive_permitted) OVERRIDE;
std::string protocol_;
diff --git a/chrome/browser/shell_integration_android.cc b/chrome/browser/shell_integration_android.cc
index af39bfa..8aa1e9b 100644
--- a/chrome/browser/shell_integration_android.cc
+++ b/chrome/browser/shell_integration_android.cc
@@ -7,9 +7,10 @@
// TODO: crbug/115375 to track implementation for following methods.
// static
-bool ShellIntegration::CanSetAsDefaultBrowser() {
+ShellIntegration::DefaultWebClientSetPermission
+ ShellIntegration::CanSetAsDefaultBrowser() {
NOTIMPLEMENTED();
- return false;
+ return SET_DEFAULT_NOT_ALLOWED;
}
// static
diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc
index cdb52ba..c170361 100644
--- a/chrome/browser/shell_integration_linux.cc
+++ b/chrome/browser/shell_integration_linux.cc
@@ -357,8 +357,9 @@ ShellIntegration::DefaultWebClientState GetIsDefaultWebClient(
} // namespace
// static
-bool ShellIntegration::CanSetAsDefaultBrowser() {
- return true;
+ShellIntegration::DefaultWebClientSetPermission
+ ShellIntegration::CanSetAsDefaultBrowser() {
+ return SET_DEFAULT_UNATTENDED;
}
// static
diff --git a/chrome/browser/shell_integration_mac.mm b/chrome/browser/shell_integration_mac.mm
index 8a52d7b..e55e42b 100644
--- a/chrome/browser/shell_integration_mac.mm
+++ b/chrome/browser/shell_integration_mac.mm
@@ -10,16 +10,21 @@
#include "chrome/common/chrome_version_info.h"
#import "third_party/mozilla/NSWorkspace+Utils.h"
-bool ShellIntegration::CanSetAsDefaultBrowser() {
- return chrome::VersionInfo::GetChannel() !=
- chrome::VersionInfo::CHANNEL_CANARY;
+ShellIntegration::DefaultWebClientSetPermission
+ ShellIntegration::CanSetAsDefaultBrowser() {
+ if (chrome::VersionInfo::GetChannel() !=
+ chrome::VersionInfo::CHANNEL_CANARY) {
+ return SET_DEFAULT_UNATTENDED;
+ }
+
+ return SET_DEFAULT_NOT_ALLOWED;
}
// Sets Chromium as default browser to be used by the operating system. This
// applies only for the current user. Returns false if this cannot be done, or
// if the operation fails.
bool ShellIntegration::SetAsDefaultBrowser() {
- if (!CanSetAsDefaultBrowser())
+ if (CanSetAsDefaultBrowser() != SET_DEFAULT_UNATTENDED)
return false;
// We really do want the outer bundle here, not the main bundle since setting
@@ -39,7 +44,7 @@ bool ShellIntegration::SetAsDefaultProtocolClient(const std::string& protocol) {
if (protocol.empty())
return false;
- if (!CanSetAsDefaultProtocolClient())
+ if (CanSetAsDefaultProtocolClient() != SET_DEFAULT_UNATTENDED)
return false;
// We really do want the main bundle here since it makes sense to set an
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index f4c8609..429649f 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -425,8 +425,15 @@ bool ActivateApplication(const string16& app_id) {
} // namespace
-bool ShellIntegration::CanSetAsDefaultBrowser() {
- return BrowserDistribution::GetDistribution()->CanSetAsDefault();
+ShellIntegration::DefaultWebClientSetPermission
+ ShellIntegration::CanSetAsDefaultBrowser() {
+ if (!BrowserDistribution::GetDistribution()->CanSetAsDefault())
+ return SET_DEFAULT_NOT_ALLOWED;
+
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8)
+ return SET_DEFAULT_INTERACTIVE;
+ else
+ return SET_DEFAULT_UNATTENDED;
}
bool ShellIntegration::SetAsDefaultBrowser() {
@@ -471,6 +478,23 @@ bool ShellIntegration::SetAsDefaultProtocolClient(const std::string& protocol) {
return true;
}
+bool ShellIntegration::SetAsDefaultBrowserInteractive() {
+ FilePath chrome_exe;
+ if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
+ NOTREACHED() << "Error getting app exe path";
+ return false;
+ }
+
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ if (!ShellUtil::ShowMakeChromeDefaultSystemUI(dist, chrome_exe.value())) {
+ LOG(ERROR) << "Failed to launch the set-default-browser Windows UI.";
+ return false;
+ }
+
+ VLOG(1) << "Set-as-default Windows UI triggered.";
+ return true;
+}
+
ShellIntegration::DefaultWebClientState ShellIntegration::IsDefaultBrowser() {
// When we check for default browser we don't necessarily want to count file
// type handlers and icons as having changed the default browser status,
diff --git a/chrome/browser/ui/cocoa/first_run_dialog.mm b/chrome/browser/ui/cocoa/first_run_dialog.mm
index 8ec5ce2..9df99fa 100644
--- a/chrome/browser/ui/cocoa/first_run_dialog.mm
+++ b/chrome/browser/ui/cocoa/first_run_dialog.mm
@@ -159,7 +159,8 @@ void ShowFirstRunDialog(Profile* profile) {
ofType:@"nib"];
if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
// Bound to the dialog checkboxes.
- makeDefaultBrowser_ = ShellIntegration::CanSetAsDefaultBrowser();
+ makeDefaultBrowser_ = ShellIntegration::CanSetAsDefaultBrowser() !=
+ ShellIntegration::SET_DEFAULT_NOT_ALLOWED;
statsEnabled_ = StatsCheckboxDefault();
}
return self;
diff --git a/chrome/browser/ui/startup/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt.cc
index 53ddb0c..06a36d0 100644
--- a/chrome/browser/ui/startup/default_browser_prompt.cc
+++ b/chrome/browser/ui/startup/default_browser_prompt.cc
@@ -31,11 +31,26 @@ using content::BrowserThread;
namespace {
+// Calls the appropriate function for setting Chrome as the default browser.
+// This requires IO access (registry) and may result in interaction with a
+// modal system UI.
+void SetChromeAsDefaultBrowser(bool interactive_flow) {
+ if (interactive_flow) {
+ UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefaultUI", 1);
+ if (!ShellIntegration::SetAsDefaultBrowserInteractive())
+ UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefaultUIFailed", 1);
+ } else {
+ UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefault", 1);
+ ShellIntegration::SetAsDefaultBrowser();
+ }
+}
+
// The delegate for the infobar shown when Chrome is not the default browser.
class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
- explicit DefaultBrowserInfoBarDelegate(InfoBarTabHelper* infobar_helper,
- PrefService* prefs);
+ DefaultBrowserInfoBarDelegate(InfoBarTabHelper* infobar_helper,
+ PrefService* prefs,
+ bool interactive_flow_required);
private:
virtual ~DefaultBrowserInfoBarDelegate();
@@ -61,6 +76,10 @@ class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
// Whether the info-bar should be dismissed on the next navigation.
bool should_expire_;
+ // Whether changing the default application will require entering the
+ // modal-UI flow.
+ const bool interactive_flow_required_;
+
// Used to delay the expiration of the info-bar.
base::WeakPtrFactory<DefaultBrowserInfoBarDelegate> weak_factory_;
@@ -69,11 +88,13 @@ class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
DefaultBrowserInfoBarDelegate::DefaultBrowserInfoBarDelegate(
InfoBarTabHelper* infobar_helper,
- PrefService* prefs)
+ PrefService* prefs,
+ bool interactive_flow_required)
: ConfirmInfoBarDelegate(infobar_helper),
prefs_(prefs),
action_taken_(false),
should_expire_(false),
+ interactive_flow_required_(interactive_flow_required),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
// We want the info-bar to stick-around for few seconds and then be hidden
// on the next navigation after that.
@@ -115,11 +136,11 @@ bool DefaultBrowserInfoBarDelegate::NeedElevation(InfoBarButton button) const {
bool DefaultBrowserInfoBarDelegate::Accept() {
action_taken_ = true;
- UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefault", 1);
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
- base::Bind(base::IgnoreResult(&ShellIntegration::SetAsDefaultBrowser)));
+ base::Bind(&SetChromeAsDefaultBrowser, interactive_flow_required_));
+
return true;
}
@@ -132,14 +153,15 @@ bool DefaultBrowserInfoBarDelegate::Cancel() {
}
void CheckDefaultBrowserCallback() {
- if (ShellIntegration::IsDefaultBrowser() ||
- !ShellIntegration::CanSetAsDefaultBrowser()) {
- return;
+ if (!ShellIntegration::IsDefaultBrowser()) {
+ ShellIntegration::DefaultWebClientSetPermission default_change_mode =
+ ShellIntegration::CanSetAsDefaultBrowser();
+
+ if (default_change_mode != ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&browser::internal::NotifyNotDefaultBrowserCallback));
+ }
}
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&browser::internal::NotifyNotDefaultBrowserCallback));
}
} // namespace
@@ -192,9 +214,12 @@ void NotifyNotDefaultBrowserCallback() {
if (infobar_helper->infobar_count() > 0)
return;
+ bool interactive_flow = ShellIntegration::CanSetAsDefaultBrowser() ==
+ ShellIntegration::SET_DEFAULT_INTERACTIVE;
infobar_helper->AddInfoBar(
new DefaultBrowserInfoBarDelegate(infobar_helper,
- tab->profile()->GetPrefs()));
+ tab->profile()->GetPrefs(),
+ interactive_flow));
}
} // namespace internal
diff --git a/chrome/browser/ui/webui/options2/browser_options_handler2.cc b/chrome/browser/ui/webui/options2/browser_options_handler2.cc
index b5f272e..2ef0580 100644
--- a/chrome/browser/ui/webui/options2/browser_options_handler2.cc
+++ b/chrome/browser/ui/webui/options2/browser_options_handler2.cc
@@ -675,7 +675,8 @@ void BrowserOptionsHandler::CheckAutoLaunchCallback(
void BrowserOptionsHandler::UpdateDefaultBrowserState() {
// Check for side-by-side first.
- if (!ShellIntegration::CanSetAsDefaultBrowser()) {
+ if (ShellIntegration::CanSetAsDefaultBrowser() ==
+ ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
SetDefaultBrowserUIString(IDS_OPTIONS_DEFAULTBROWSER_SXS);
return;
}
@@ -742,6 +743,10 @@ void BrowserOptionsHandler::SetDefaultWebClientUIState(
SetDefaultBrowserUIString(status_string_id);
}
+bool BrowserOptionsHandler::IsInteractiveSetDefaultPermitted() {
+ return true; // This is UI so we can allow it.
+}
+
void BrowserOptionsHandler::SetDefaultBrowserUIString(int status_string_id) {
scoped_ptr<Value> status_string(Value::CreateStringValue(
l10n_util::GetStringFUTF16(status_string_id,
diff --git a/chrome/browser/ui/webui/options2/browser_options_handler2.h b/chrome/browser/ui/webui/options2/browser_options_handler2.h
index d7ddbb0..2bd9731 100644
--- a/chrome/browser/ui/webui/options2/browser_options_handler2.h
+++ b/chrome/browser/ui/webui/options2/browser_options_handler2.h
@@ -58,6 +58,7 @@ class BrowserOptionsHandler
// ShellIntegration::DefaultWebClientObserver implementation.
virtual void SetDefaultWebClientUIState(
ShellIntegration::DefaultWebClientUIState state) OVERRIDE;
+ virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE;
// TemplateURLServiceObserver implementation.
virtual void OnTemplateURLServiceChanged() OVERRIDE;
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index ef7177e..850f3c1 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -611,6 +611,23 @@ bool AnotherUserHasDefaultBrowser(BrowserDistribution* dist,
return true;
}
+// Launches the Windows 7 and Windows 8 dialog for picking the application to
+// handle the given protocol. Most importantly, this is used to set the default
+// handler for http (and, implicitly with it, https). In that case it is also
+// known as the 'how do you want to open webpages' dialog.
+// It is required that Chrome be already *registered* for the given protocol.
+bool LaunchSelectDefaultProtocolHandlerDialog(const wchar_t* protocol) {
+ DCHECK(protocol);
+ OPENASINFO open_as_info = {};
+ open_as_info.pcszFile = protocol;
+ open_as_info.oaifInFlags =
+ OAIF_URL_PROTOCOL | OAIF_FORCE_REGISTRATION | OAIF_REGISTER_EXT;
+ HRESULT hr = SHOpenWithDialog(NULL, &open_as_info);
+ DLOG_IF(WARNING, FAILED(hr)) << "Failed to set as default " << protocol
+ << " handler; hr=0x" << std::hex << hr;
+ return SUCCEEDED(hr);
+}
+
// Launches the Windows 7 and Windows 8 application association dialog, which
// is the only documented way to make a browser the default browser on
// Windows 8.
@@ -945,6 +962,14 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist,
if (!dist->CanSetAsDefault())
return false;
+ // Windows 8 does not permit making a browser default just like that.
+ // This process needs to be routed through the system's UI. Use
+ // ShowMakeChromeDefaultSystemUI instead (below).
+ if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
+ NOTREACHED();
+ return false;
+ }
+
ShellUtil::RegisterChromeBrowser(dist, chrome_exe, L"", elevate_if_not_admin);
bool ret = true;
@@ -955,17 +980,7 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist,
if (ShellUtil::GetUserSpecificDefaultBrowserSuffix(dist, &app_suffix))
app_name += app_suffix;
- if (base::win::GetVersion() >= base::win::VERSION_WIN8) {
- // On Windows 8, you can't set yourself as the default handler
- // programatically. In other words IApplicationAssociationRegistration
- // has been rendered useless. What you can do is to launch
- // "Set Program Associations" section of the "Default Programs"
- // control panel. This action does not require elevation and we
- // don't get to control window activation. More info at:
- // http://msdn.microsoft.com/en-us/library/cc144154(VS.85).aspx
- return LaunchApplicationAssociationDialog(app_name.c_str());
-
- } else if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
// On Windows Vista and Win7 we still can set ourselves via the
// the IApplicationAssociationRegistration interface.
VLOG(1) << "Registering Chrome as default browser on Vista.";
@@ -1027,6 +1042,24 @@ bool ShellUtil::MakeChromeDefault(BrowserDistribution* dist,
return ret;
}
+bool ShellUtil::ShowMakeChromeDefaultSystemUI(BrowserDistribution* dist,
+ const string16& chrome_exe) {
+ DCHECK_GE(base::win::GetVersion(), base::win::VERSION_WIN8);
+ if (!dist->CanSetAsDefault())
+ return false;
+
+ if (!RegisterChromeBrowser(dist, chrome_exe, string16(), true))
+ return false;
+
+ // On Windows 8, you can't set yourself as the default handler
+ // programatically. In other words IApplicationAssociationRegistration
+ // has been rendered useless. What you can do is to launch
+ // "Set Program Associations" section of the "Default Programs"
+ // control panel, which is a mess, or pop the concise "How you want to open
+ // webpages?" dialog. We choose the latter.
+ return LaunchSelectDefaultProtocolHandlerDialog(L"http");
+}
+
bool ShellUtil::MakeChromeDefaultProtocolClient(BrowserDistribution* dist,
const string16& chrome_exe,
const string16& protocol) {
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index 85e5fbd..4215ce8 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -237,6 +237,15 @@ class ShellUtil {
const string16& chrome_exe,
bool elevate_if_not_admin);
+ // Shows to the user a system dialog where Chrome can be set as the
+ // default browser. This is intended for Windows 8 and above only.
+ // This is a blocking call.
+ //
+ // |dist| gives the type of browser distribution currently in use.
+ // |chrome_exe| The chrome.exe path to register as default browser.
+ static bool ShowMakeChromeDefaultSystemUI(BrowserDistribution* dist,
+ const string16& chrome_exe);
+
// Make Chrome the default application for a protocol.
// chrome_exe: The chrome.exe path to register as default browser.
// protocol: The protocol to register as the default handler for.