| Index: chrome/browser/ui/startup/default_browser_prompt.cc
|
| diff --git a/chrome/browser/ui/startup/default_browser_prompt.cc b/chrome/browser/ui/startup/default_browser_prompt.cc
|
| index 67199bf78eebac98fb2960f5c88f74f681ae8266..ce1585d507f7a7cfaeca528111b8e59d441d55c4 100644
|
| --- a/chrome/browser/ui/startup/default_browser_prompt.cc
|
| +++ b/chrome/browser/ui/startup/default_browser_prompt.cc
|
| @@ -8,14 +8,13 @@
|
|
|
| #include "base/location.h"
|
| #include "base/memory/weak_ptr.h"
|
| -#include "base/metrics/histogram.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| #include "base/prefs/pref_registry_simple.h"
|
| #include "base/prefs/pref_service.h"
|
| #include "base/single_thread_task_runner.h"
|
| #include "base/thread_task_runner_handle.h"
|
| #include "base/version.h"
|
| #include "chrome/browser/browser_process.h"
|
| -#include "chrome/browser/first_run/first_run.h"
|
| #include "chrome/browser/infobars/infobar_service.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/profiles/profile_manager.h"
|
| @@ -26,12 +25,9 @@
|
| #include "chrome/common/pref_names.h"
|
| #include "chrome/grit/chromium_strings.h"
|
| #include "chrome/grit/generated_resources.h"
|
| -#include "chrome/installer/util/master_preferences.h"
|
| -#include "chrome/installer/util/master_preferences_constants.h"
|
| #include "components/infobars/core/confirm_infobar_delegate.h"
|
| #include "components/infobars/core/infobar.h"
|
| #include "components/version_info/version_info.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| #include "content/public/browser/navigation_details.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "grit/theme_resources.h"
|
| @@ -40,39 +36,80 @@
|
|
|
| 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, PrefService* prefs) {
|
| - if (interactive_flow) {
|
| +// A ShellIntegration::DefaultWebClientObserver that records user metrics for
|
| +// the result of making Chrome the default browser.
|
| +class SetDefaultBrowserObserver
|
| + : public ShellIntegration::DefaultWebClientObserver {
|
| + public:
|
| + SetDefaultBrowserObserver();
|
| + ~SetDefaultBrowserObserver() override;
|
| +
|
| + private:
|
| + void SetDefaultWebClientUIState(
|
| + ShellIntegration::DefaultWebClientUIState state) override;
|
| + void OnSetAsDefaultConcluded(bool succeeded) override;
|
| + bool IsOwnedByWorker() override;
|
| + bool IsInteractiveSetDefaultPermitted() override;
|
| +
|
| + // True if an interactive flow will be used (i.e., Windows 8+).
|
| + bool interactive_;
|
| +
|
| + // The result of the call to ShellIntegration::SetAsDefaultBrowser() or
|
| + // ShellIntegration::SetAsDefaultBrowserInteractive().
|
| + bool interaction_succeeded_ = false;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(SetDefaultBrowserObserver);
|
| +};
|
| +
|
| +SetDefaultBrowserObserver::SetDefaultBrowserObserver()
|
| + : interactive_(ShellIntegration::CanSetAsDefaultBrowser() ==
|
| + ShellIntegration::SET_DEFAULT_INTERACTIVE) {
|
| + // Log that an attempt is about to be made to set one way or the other.
|
| + if (interactive_)
|
| UMA_HISTOGRAM_BOOLEAN("DefaultBrowserWarning.SetAsDefaultUI", true);
|
| - if (!ShellIntegration::SetAsDefaultBrowserInteractive()) {
|
| - UMA_HISTOGRAM_BOOLEAN("DefaultBrowserWarning.SetAsDefaultUIFailed", true);
|
| - } else if (ShellIntegration::GetDefaultBrowser() ==
|
| - ShellIntegration::NOT_DEFAULT) {
|
| - // If the interaction succeeded but we are still not the default browser
|
| - // it likely means the user simply selected another browser from the
|
| - // panel. We will respect this choice and write it down as 'no, thanks'.
|
| - UMA_HISTOGRAM_BOOLEAN("DefaultBrowserWarning.DontSetAsDefault", true);
|
| - }
|
| - } else {
|
| + else
|
| UMA_HISTOGRAM_BOOLEAN("DefaultBrowserWarning.SetAsDefault", true);
|
| - ShellIntegration::SetAsDefaultBrowser();
|
| +}
|
| +
|
| +SetDefaultBrowserObserver::~SetDefaultBrowserObserver() {}
|
| +
|
| +void SetDefaultBrowserObserver::SetDefaultWebClientUIState(
|
| + ShellIntegration::DefaultWebClientUIState state) {
|
| + if (interactive_ && interaction_succeeded_ &&
|
| + state == ShellIntegration::STATE_NOT_DEFAULT) {
|
| + // The interactive flow succeeded, yet Chrome is not the default browser.
|
| + // This likely means that the user selected another browser from the panel.
|
| + // Consider this the same as canceling the infobar.
|
| + UMA_HISTOGRAM_BOOLEAN("DefaultBrowserWarning.DontSetAsDefault", true);
|
| + }
|
| +}
|
| +
|
| +void SetDefaultBrowserObserver::OnSetAsDefaultConcluded(bool succeeded) {
|
| + interaction_succeeded_ = succeeded;
|
| + if (interactive_ && !succeeded) {
|
| + // Log that the interactive flow failed.
|
| + UMA_HISTOGRAM_BOOLEAN("DefaultBrowserWarning.SetAsDefaultUIFailed", true);
|
| }
|
| }
|
|
|
| +bool SetDefaultBrowserObserver::IsOwnedByWorker() {
|
| + // Instruct the DefaultBrowserWorker to delete this instance when it is done.
|
| + return true;
|
| +}
|
| +
|
| +bool SetDefaultBrowserObserver::IsInteractiveSetDefaultPermitted() {
|
| + return true;
|
| +}
|
| +
|
| // The delegate for the infobar shown when Chrome is not the default browser.
|
| class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
|
| public:
|
| // Creates a default browser infobar and delegate and adds the infobar to
|
| // |infobar_service|.
|
| - static void Create(InfoBarService* infobar_service,
|
| - PrefService* prefs,
|
| - bool interactive_flow_required);
|
| + static void Create(InfoBarService* infobar_service, PrefService* prefs);
|
|
|
| private:
|
| - DefaultBrowserInfoBarDelegate(PrefService* prefs,
|
| - bool interactive_flow_required);
|
| + explicit DefaultBrowserInfoBarDelegate(PrefService* prefs);
|
| ~DefaultBrowserInfoBarDelegate() override;
|
|
|
| void AllowExpiry() { should_expire_ = true; }
|
| @@ -95,10 +132,6 @@ 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_;
|
|
|
| @@ -107,21 +140,17 @@ class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
|
|
|
| // static
|
| void DefaultBrowserInfoBarDelegate::Create(InfoBarService* infobar_service,
|
| - PrefService* prefs,
|
| - bool interactive_flow_required) {
|
| - infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
|
| - scoped_ptr<ConfirmInfoBarDelegate>(new DefaultBrowserInfoBarDelegate(
|
| - prefs, interactive_flow_required))));
|
| + PrefService* prefs) {
|
| + infobar_service->AddInfoBar(
|
| + infobar_service->CreateConfirmInfoBar(scoped_ptr<ConfirmInfoBarDelegate>(
|
| + new DefaultBrowserInfoBarDelegate(prefs))));
|
| }
|
|
|
| -DefaultBrowserInfoBarDelegate::DefaultBrowserInfoBarDelegate(
|
| - PrefService* prefs,
|
| - bool interactive_flow_required)
|
| +DefaultBrowserInfoBarDelegate::DefaultBrowserInfoBarDelegate(PrefService* prefs)
|
| : ConfirmInfoBarDelegate(),
|
| prefs_(prefs),
|
| action_taken_(false),
|
| should_expire_(false),
|
| - interactive_flow_required_(interactive_flow_required),
|
| weak_factory_(this) {
|
| // We want the info-bar to stick-around for few seconds and then be hidden
|
| // on the next navigation after that.
|
| @@ -165,11 +194,9 @@ bool DefaultBrowserInfoBarDelegate::OKButtonTriggersUACPrompt() const {
|
|
|
| bool DefaultBrowserInfoBarDelegate::Accept() {
|
| action_taken_ = true;
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&SetChromeAsDefaultBrowser, interactive_flow_required_,
|
| - prefs_));
|
| -
|
| + scoped_refptr<ShellIntegration::DefaultBrowserWorker>(
|
| + new ShellIntegration::DefaultBrowserWorker(new SetDefaultBrowserObserver))
|
| + ->StartSetAsDefault();
|
| return true;
|
| }
|
|
|
| @@ -181,8 +208,73 @@ bool DefaultBrowserInfoBarDelegate::Cancel() {
|
| return true;
|
| }
|
|
|
| -void NotifyNotDefaultBrowserCallback(chrome::HostDesktopType desktop_type) {
|
| - Browser* browser = chrome::FindLastActiveWithHostDesktopType(desktop_type);
|
| +// A ShellIntegration::DefaultWebClientObserver that handles the check to
|
| +// determine whether or not to show the default browser prompt. If Chrome is the
|
| +// default browser, then the kCheckDefaultBrowser pref is reset. Otherwise, the
|
| +// prompt is shown.
|
| +class CheckDefaultBrowserObserver
|
| + : public ShellIntegration::DefaultWebClientObserver {
|
| + public:
|
| + CheckDefaultBrowserObserver(const base::FilePath& profile_path,
|
| + bool show_prompt,
|
| + chrome::HostDesktopType desktop_type);
|
| + ~CheckDefaultBrowserObserver() override;
|
| +
|
| + private:
|
| + void SetDefaultWebClientUIState(
|
| + ShellIntegration::DefaultWebClientUIState state) override;
|
| + bool IsOwnedByWorker() override;
|
| +
|
| + void ResetCheckDefaultBrowserPref();
|
| + void ShowPrompt();
|
| +
|
| + // The path to the profile for which the prompt is to be shown.
|
| + base::FilePath profile_path_;
|
| +
|
| + // True if the prompt is to be shown if Chrome is not the default browser.
|
| + bool show_prompt_;
|
| + chrome::HostDesktopType desktop_type_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CheckDefaultBrowserObserver);
|
| +};
|
| +
|
| +CheckDefaultBrowserObserver::CheckDefaultBrowserObserver(
|
| + const base::FilePath& profile_path,
|
| + bool show_prompt,
|
| + chrome::HostDesktopType desktop_type)
|
| + : profile_path_(profile_path),
|
| + show_prompt_(show_prompt),
|
| + desktop_type_(desktop_type) {}
|
| +
|
| +CheckDefaultBrowserObserver::~CheckDefaultBrowserObserver() {}
|
| +
|
| +void CheckDefaultBrowserObserver::SetDefaultWebClientUIState(
|
| + ShellIntegration::DefaultWebClientUIState state) {
|
| + if (state == ShellIntegration::STATE_IS_DEFAULT) {
|
| + // Notify the user in the future if Chrome ceases to be the user's chosen
|
| + // default browser.
|
| + ResetCheckDefaultBrowserPref();
|
| + } else if (show_prompt_ && state == ShellIntegration::STATE_NOT_DEFAULT &&
|
| + ShellIntegration::CanSetAsDefaultBrowser() !=
|
| + ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
|
| + ShowPrompt();
|
| + }
|
| +}
|
| +
|
| +bool CheckDefaultBrowserObserver::IsOwnedByWorker() {
|
| + // Instruct the DefaultBrowserWorker to delete this instance when it is done.
|
| + return true;
|
| +}
|
| +
|
| +void CheckDefaultBrowserObserver::ResetCheckDefaultBrowserPref() {
|
| + Profile* profile =
|
| + g_browser_process->profile_manager()->GetProfileByPath(profile_path_);
|
| + if (profile)
|
| + profile->GetPrefs()->SetBoolean(prefs::kCheckDefaultBrowser, true);
|
| +}
|
| +
|
| +void CheckDefaultBrowserObserver::ShowPrompt() {
|
| + Browser* browser = chrome::FindLastActiveWithHostDesktopType(desktop_type_);
|
| if (!browser)
|
| return; // Reached during ui tests.
|
|
|
| @@ -195,43 +287,8 @@ void NotifyNotDefaultBrowserCallback(chrome::HostDesktopType desktop_type) {
|
|
|
| DefaultBrowserInfoBarDelegate::Create(
|
| InfoBarService::FromWebContents(web_contents),
|
| - Profile::FromBrowserContext(
|
| - web_contents->GetBrowserContext())->GetPrefs(),
|
| - (ShellIntegration::CanSetAsDefaultBrowser() ==
|
| - ShellIntegration::SET_DEFAULT_INTERACTIVE));
|
| -}
|
| -
|
| -void ResetCheckDefaultBrowserPrefOnUIThread(
|
| - const base::FilePath& profile_path) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
| - Profile* profile =
|
| - g_browser_process->profile_manager()->GetProfileByPath(profile_path);
|
| - if (profile)
|
| - profile->GetPrefs()->SetBoolean(prefs::kCheckDefaultBrowser, true);
|
| -}
|
| -
|
| -void CheckDefaultBrowserOnFileThread(const base::FilePath& profile_path,
|
| - bool show_prompt,
|
| - chrome::HostDesktopType desktop_type) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
| - ShellIntegration::DefaultWebClientState state =
|
| - ShellIntegration::GetDefaultBrowser();
|
| - if (state == ShellIntegration::IS_DEFAULT) {
|
| - // Notify the user in the future if Chrome ceases to be the user's chosen
|
| - // default browser.
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&ResetCheckDefaultBrowserPrefOnUIThread, profile_path));
|
| - } else if (show_prompt && state == ShellIntegration::NOT_DEFAULT) {
|
| - ShellIntegration::DefaultWebClientSetPermission default_change_mode =
|
| - ShellIntegration::CanSetAsDefaultBrowser();
|
| -
|
| - if (default_change_mode != ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::UI, FROM_HERE,
|
| - base::Bind(&NotifyNotDefaultBrowserCallback, desktop_type));
|
| - }
|
| - }
|
| + Profile::FromBrowserContext(web_contents->GetBrowserContext())
|
| + ->GetPrefs());
|
| }
|
|
|
| } // namespace
|
| @@ -271,10 +328,11 @@ void ShowDefaultBrowserPrompt(Profile* profile, HostDesktopType desktop_type) {
|
| }
|
| }
|
|
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&CheckDefaultBrowserOnFileThread, profile->GetPath(),
|
| - show_prompt, desktop_type));
|
| + scoped_refptr<ShellIntegration::DefaultBrowserWorker>(
|
| + new ShellIntegration::DefaultBrowserWorker(
|
| + new CheckDefaultBrowserObserver(profile->GetPath(), show_prompt,
|
| + desktop_type)))
|
| + ->StartCheckIsDefault();
|
| }
|
|
|
| #if !defined(OS_WIN)
|
|
|