diff options
-rw-r--r-- | chrome/browser/custom_handlers/protocol_handler_registry.cc | 3 | ||||
-rw-r--r-- | chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/external_protocol/external_protocol_handler_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run.cc | 5 | ||||
-rw-r--r-- | chrome/browser/shell_integration.cc | 30 | ||||
-rw-r--r-- | chrome/browser/shell_integration.h | 35 | ||||
-rw-r--r-- | chrome/browser/shell_integration_android.cc | 5 | ||||
-rw-r--r-- | chrome/browser/shell_integration_linux.cc | 5 | ||||
-rw-r--r-- | chrome/browser/shell_integration_mac.mm | 15 | ||||
-rw-r--r-- | chrome/browser/shell_integration_win.cc | 28 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/first_run_dialog.mm | 3 | ||||
-rw-r--r-- | chrome/browser/ui/startup/default_browser_prompt.cc | 51 | ||||
-rw-r--r-- | chrome/browser/ui/webui/options2/browser_options_handler2.cc | 7 | ||||
-rw-r--r-- | chrome/browser/ui/webui/options2/browser_options_handler2.h | 1 | ||||
-rw-r--r-- | chrome/installer/util/shell_util.cc | 55 | ||||
-rw-r--r-- | chrome/installer/util/shell_util.h | 9 |
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. |