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) |