Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / startup / default_browser_prompt.cc
blob786dcadd3428168e5a94a10917268feba1ed3871
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/startup/default_browser_prompt.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h"
10 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/version.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/first_run/first_run.h"
15 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
16 #include "chrome/browser/infobars/infobar_service.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/shell_integration.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_finder.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/installer/util/master_preferences.h"
25 #include "chrome/installer/util/master_preferences_constants.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/navigation_details.h"
28 #include "content/public/browser/web_contents.h"
29 #include "grit/chromium_strings.h"
30 #include "grit/generated_resources.h"
31 #include "grit/theme_resources.h"
32 #include "ui/base/l10n/l10n_util.h"
35 namespace {
37 // Calls the appropriate function for setting Chrome as the default browser.
38 // This requires IO access (registry) and may result in interaction with a
39 // modal system UI.
40 void SetChromeAsDefaultBrowser(bool interactive_flow, PrefService* prefs) {
41 if (interactive_flow) {
42 UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefaultUI", 1);
43 if (!ShellIntegration::SetAsDefaultBrowserInteractive()) {
44 UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefaultUIFailed", 1);
45 } else if (ShellIntegration::GetDefaultBrowser() ==
46 ShellIntegration::NOT_DEFAULT) {
47 // If the interaction succeeded but we are still not the default browser
48 // it likely means the user simply selected another browser from the
49 // panel. We will respect this choice and write it down as 'no, thanks'.
50 UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.DontSetAsDefault", 1);
52 } else {
53 UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.SetAsDefault", 1);
54 ShellIntegration::SetAsDefaultBrowser();
58 // The delegate for the infobar shown when Chrome is not the default browser.
59 class DefaultBrowserInfoBarDelegate : public ConfirmInfoBarDelegate {
60 public:
61 // Creates a default browser infobar delegate and adds it to
62 // |infobar_service|.
63 static void Create(InfoBarService* infobar_service,
64 PrefService* prefs,
65 bool interactive_flow_required);
67 private:
68 DefaultBrowserInfoBarDelegate(InfoBarService* infobar_service,
69 PrefService* prefs,
70 bool interactive_flow_required);
71 virtual ~DefaultBrowserInfoBarDelegate();
73 void AllowExpiry() { should_expire_ = true; }
75 // ConfirmInfoBarDelegate:
76 virtual int GetIconID() const OVERRIDE;
77 virtual string16 GetMessageText() const OVERRIDE;
78 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
79 virtual bool NeedElevation(InfoBarButton button) const OVERRIDE;
80 virtual bool Accept() OVERRIDE;
81 virtual bool Cancel() OVERRIDE;
82 virtual bool ShouldExpireInternal(
83 const content::LoadCommittedDetails& details) const OVERRIDE;
85 // The prefs to use.
86 PrefService* prefs_;
88 // Whether the user clicked one of the buttons.
89 bool action_taken_;
91 // Whether the info-bar should be dismissed on the next navigation.
92 bool should_expire_;
94 // Whether changing the default application will require entering the
95 // modal-UI flow.
96 const bool interactive_flow_required_;
98 // Used to delay the expiration of the info-bar.
99 base::WeakPtrFactory<DefaultBrowserInfoBarDelegate> weak_factory_;
101 DISALLOW_COPY_AND_ASSIGN(DefaultBrowserInfoBarDelegate);
104 // static
105 void DefaultBrowserInfoBarDelegate::Create(InfoBarService* infobar_service,
106 PrefService* prefs,
107 bool interactive_flow_required) {
108 infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
109 new DefaultBrowserInfoBarDelegate(infobar_service, prefs,
110 interactive_flow_required)));
113 DefaultBrowserInfoBarDelegate::DefaultBrowserInfoBarDelegate(
114 InfoBarService* infobar_service,
115 PrefService* prefs,
116 bool interactive_flow_required)
117 : ConfirmInfoBarDelegate(infobar_service),
118 prefs_(prefs),
119 action_taken_(false),
120 should_expire_(false),
121 interactive_flow_required_(interactive_flow_required),
122 weak_factory_(this) {
123 // We want the info-bar to stick-around for few seconds and then be hidden
124 // on the next navigation after that.
125 base::MessageLoop::current()->PostDelayedTask(
126 FROM_HERE,
127 base::Bind(&DefaultBrowserInfoBarDelegate::AllowExpiry,
128 weak_factory_.GetWeakPtr()),
129 base::TimeDelta::FromSeconds(8));
132 DefaultBrowserInfoBarDelegate::~DefaultBrowserInfoBarDelegate() {
133 if (!action_taken_)
134 UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.Ignored", 1);
137 int DefaultBrowserInfoBarDelegate::GetIconID() const {
138 return IDR_PRODUCT_LOGO_32;
141 string16 DefaultBrowserInfoBarDelegate::GetMessageText() const {
142 return l10n_util::GetStringUTF16(IDS_DEFAULT_BROWSER_INFOBAR_SHORT_TEXT);
145 string16 DefaultBrowserInfoBarDelegate::GetButtonLabel(
146 InfoBarButton button) const {
147 return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
148 IDS_SET_AS_DEFAULT_INFOBAR_BUTTON_LABEL :
149 IDS_DONT_ASK_AGAIN_INFOBAR_BUTTON_LABEL);
152 bool DefaultBrowserInfoBarDelegate::NeedElevation(InfoBarButton button) const {
153 return button == BUTTON_OK;
156 bool DefaultBrowserInfoBarDelegate::Accept() {
157 action_taken_ = true;
158 content::BrowserThread::PostTask(
159 content::BrowserThread::FILE, FROM_HERE,
160 base::Bind(&SetChromeAsDefaultBrowser, interactive_flow_required_,
161 prefs_));
163 return true;
166 bool DefaultBrowserInfoBarDelegate::Cancel() {
167 action_taken_ = true;
168 UMA_HISTOGRAM_COUNTS("DefaultBrowserWarning.DontSetAsDefault", 1);
169 // User clicked "Don't ask me again", remember that.
170 prefs_->SetBoolean(prefs::kCheckDefaultBrowser, false);
171 return true;
174 bool DefaultBrowserInfoBarDelegate::ShouldExpireInternal(
175 const content::LoadCommittedDetails& details) const {
176 return should_expire_;
179 void NotifyNotDefaultBrowserCallback(chrome::HostDesktopType desktop_type) {
180 Browser* browser = chrome::FindLastActiveWithHostDesktopType(desktop_type);
181 if (!browser)
182 return; // Reached during ui tests.
184 // In ChromeBot tests, there might be a race. This line appears to get
185 // called during shutdown and |tab| can be NULL.
186 content::WebContents* web_contents =
187 browser->tab_strip_model()->GetActiveWebContents();
188 if (!web_contents)
189 return;
191 DefaultBrowserInfoBarDelegate::Create(
192 InfoBarService::FromWebContents(web_contents),
193 Profile::FromBrowserContext(
194 web_contents->GetBrowserContext())->GetPrefs(),
195 (ShellIntegration::CanSetAsDefaultBrowser() ==
196 ShellIntegration::SET_DEFAULT_INTERACTIVE));
199 void CheckDefaultBrowserCallback(chrome::HostDesktopType desktop_type) {
200 if (ShellIntegration::GetDefaultBrowser() == ShellIntegration::NOT_DEFAULT) {
201 ShellIntegration::DefaultWebClientSetPermission default_change_mode =
202 ShellIntegration::CanSetAsDefaultBrowser();
204 if (default_change_mode != ShellIntegration::SET_DEFAULT_NOT_ALLOWED) {
205 content::BrowserThread::PostTask(
206 content::BrowserThread::UI, FROM_HERE,
207 base::Bind(&NotifyNotDefaultBrowserCallback, desktop_type));
212 } // namespace
214 namespace chrome {
216 void RegisterDefaultBrowserPromptPrefs(PrefRegistrySimple* registry) {
217 registry->RegisterStringPref(
218 prefs::kBrowserSuppressDefaultBrowserPrompt, std::string());
221 void ShowDefaultBrowserPrompt(Profile* profile, HostDesktopType desktop_type) {
222 // We do not check if we are the default browser if:
223 // - The user said "don't ask me again" on the infobar earlier.
224 // - There is a policy in control of this setting.
225 // - The "suppress_default_browser_prompt_for_version" master preference is
226 // set to the current version.
227 if (!profile->GetPrefs()->GetBoolean(prefs::kCheckDefaultBrowser))
228 return;
230 if (g_browser_process->local_state()->IsManagedPreference(
231 prefs::kDefaultBrowserSettingEnabled)) {
232 if (g_browser_process->local_state()->GetBoolean(
233 prefs::kDefaultBrowserSettingEnabled)) {
234 content::BrowserThread::PostTask(
235 content::BrowserThread::FILE, FROM_HERE,
236 base::Bind(
237 base::IgnoreResult(&ShellIntegration::SetAsDefaultBrowser)));
238 } else {
239 // TODO(pastarmovj): We can't really do anything meaningful here yet but
240 // just prevent showing the infobar.
242 return;
245 const std::string disable_version_string =
246 g_browser_process->local_state()->GetString(
247 prefs::kBrowserSuppressDefaultBrowserPrompt);
248 const Version disable_version(disable_version_string);
249 DCHECK(disable_version_string.empty() || disable_version.IsValid());
250 if (disable_version.IsValid()) {
251 const chrome::VersionInfo version_info;
252 if (disable_version.Equals(Version(version_info.Version())))
253 return;
256 content::BrowserThread::PostTask(
257 content::BrowserThread::FILE, FROM_HERE,
258 base::Bind(&CheckDefaultBrowserCallback, desktop_type));
262 #if !defined(OS_WIN)
263 bool ShowFirstRunDefaultBrowserPrompt(Profile* profile) {
264 return false;
266 #endif
268 } // namespace chrome