Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / webui / set_as_default_browser_ui.cc
blob9645460e30b7144161504473e654c3ad81676522
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/webui/set_as_default_browser_ui.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/metrics/histogram.h"
11 #include "base/prefs/pref_service.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/shell_integration.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_dialogs.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/browser/ui/browser_list.h"
18 #include "chrome/browser/ui/browser_list_observer.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/browser/ui/chrome_pages.h"
21 #include "chrome/browser/ui/singleton_tabs.h"
22 #include "chrome/browser/ui/sync/sync_promo_ui.h"
23 #include "chrome/browser/ui/tabs/tab_strip_model.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/common/url_constants.h"
26 #include "chrome/grit/generated_resources.h"
27 #include "chrome/grit/locale_settings.h"
28 #include "chrome/installer/util/install_util.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/browser/web_contents_delegate.h"
32 #include "content/public/browser/web_ui.h"
33 #include "content/public/browser/web_ui_data_source.h"
34 #include "content/public/browser/web_ui_message_handler.h"
35 #include "grit/browser_resources.h"
36 #include "ui/base/l10n/l10n_font_util.h"
37 #include "ui/base/l10n/l10n_util.h"
38 #include "ui/gfx/font.h"
39 #include "ui/views/widget/widget.h"
40 #include "ui/web_dialogs/web_dialog_delegate.h"
42 using content::BrowserThread;
43 using content::WebContents;
44 using content::WebUIMessageHandler;
46 namespace {
48 const char kSetAsDefaultBrowserHistogram[] = "DefaultBrowser.InteractionResult";
50 // The enum permits registering in UMA the three possible outcomes (do not
51 // reorder these).
52 // ACCEPTED: user pressed Next and made Chrome default.
53 // DECLINED: user simply closed the dialog without making Chrome default.
54 // REGRETTED: user pressed Next but then elected a different default browser.
55 enum MakeChromeDefaultResult {
56 MAKE_CHROME_DEFAULT_ACCEPTED = 0,
57 MAKE_CHROME_DEFAULT_DECLINED = 1,
58 MAKE_CHROME_DEFAULT_REGRETTED = 2,
59 // MAKE_CHROME_DEFAULT_ACCEPTED_IMMERSE = 3, // Deprecated.
60 MAKE_CHROME_DEFAULT_MAX
63 content::WebUIDataSource* CreateSetAsDefaultBrowserUIHTMLSource() {
64 content::WebUIDataSource* data_source = content::WebUIDataSource::Create(
65 chrome::kChromeUIMetroFlowHost);
66 data_source->AddLocalizedString("page-title", IDS_METRO_FLOW_TAB_TITLE);
67 data_source->AddLocalizedString("flowTitle", IDS_METRO_FLOW_TITLE_SHORT);
68 data_source->AddLocalizedString("flowDescription",
69 IDS_METRO_FLOW_DESCRIPTION);
70 data_source->AddLocalizedString("flowNext",
71 IDS_METRO_FLOW_SET_DEFAULT);
72 data_source->AddLocalizedString("chromeLogoString",
73 IDS_METRO_FLOW_LOGO_STRING_ALT);
74 data_source->SetJsonPath("strings.js");
75 data_source->AddResourcePath("set_as_default_browser.js",
76 IDR_SET_AS_DEFAULT_BROWSER_JS);
77 data_source->SetDefaultResource(IDR_SET_AS_DEFAULT_BROWSER_HTML);
78 return data_source;
81 // A simple class serving as a delegate for passing down the result of the
82 // interaction.
83 class ResponseDelegate {
84 public:
85 virtual void SetDialogInteractionResult(MakeChromeDefaultResult result) = 0;
87 protected:
88 virtual ~ResponseDelegate() { }
91 // Event handler for SetAsDefaultBrowserUI. Capable of setting Chrome as the
92 // default browser on button click, closing itself and triggering Chrome
93 // restart.
94 class SetAsDefaultBrowserHandler
95 : public WebUIMessageHandler,
96 public base::SupportsWeakPtr<SetAsDefaultBrowserHandler>,
97 public ShellIntegration::DefaultWebClientObserver {
98 public:
99 explicit SetAsDefaultBrowserHandler(
100 const base::WeakPtr<ResponseDelegate>& response_delegate);
101 virtual ~SetAsDefaultBrowserHandler();
103 // WebUIMessageHandler implementation.
104 virtual void RegisterMessages() override;
106 // ShellIntegration::DefaultWebClientObserver implementation.
107 virtual void SetDefaultWebClientUIState(
108 ShellIntegration::DefaultWebClientUIState state) override;
109 virtual void OnSetAsDefaultConcluded(bool close_chrome) override;
110 virtual bool IsInteractiveSetDefaultPermitted() override;
112 private:
113 // Handler for the 'Next' (or 'make Chrome the Metro browser') button.
114 void HandleLaunchSetDefaultBrowserFlow(const base::ListValue* args);
116 // Close this web ui.
117 void ConcludeInteraction(MakeChromeDefaultResult interaction_result);
119 scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_;
120 bool set_default_returned_;
121 bool set_default_result_;
122 base::WeakPtr<ResponseDelegate> response_delegate_;
124 DISALLOW_COPY_AND_ASSIGN(SetAsDefaultBrowserHandler);
127 SetAsDefaultBrowserHandler::SetAsDefaultBrowserHandler(
128 const base::WeakPtr<ResponseDelegate>& response_delegate)
129 : default_browser_worker_(new ShellIntegration::DefaultBrowserWorker(this)),
130 set_default_returned_(false), set_default_result_(false),
131 response_delegate_(response_delegate) {
134 SetAsDefaultBrowserHandler::~SetAsDefaultBrowserHandler() {
135 default_browser_worker_->ObserverDestroyed();
138 void SetAsDefaultBrowserHandler::RegisterMessages() {
139 web_ui()->RegisterMessageCallback(
140 "SetAsDefaultBrowser:LaunchSetDefaultBrowserFlow",
141 base::Bind(&SetAsDefaultBrowserHandler::HandleLaunchSetDefaultBrowserFlow,
142 base::Unretained(this)));
145 void SetAsDefaultBrowserHandler::SetDefaultWebClientUIState(
146 ShellIntegration::DefaultWebClientUIState state) {
147 // The callback is expected to be invoked once the procedure has completed.
148 DCHECK_CURRENTLY_ON(BrowserThread::UI);
149 if (!set_default_returned_)
150 return;
152 if (state == ShellIntegration::STATE_NOT_DEFAULT && set_default_result_) {
153 // The operation concluded, but Chrome is still not the default.
154 // If the call has succeeded, this suggests user has decided not to make
155 // chrome the default.
156 ConcludeInteraction(MAKE_CHROME_DEFAULT_REGRETTED);
157 } else if (state == ShellIntegration::STATE_IS_DEFAULT) {
158 ConcludeInteraction(MAKE_CHROME_DEFAULT_ACCEPTED);
161 // Otherwise, keep the dialog open since the user probably didn't make a
162 // choice.
165 void SetAsDefaultBrowserHandler::OnSetAsDefaultConcluded(bool call_result) {
166 set_default_returned_ = true;
167 set_default_result_ = call_result;
170 bool SetAsDefaultBrowserHandler::IsInteractiveSetDefaultPermitted() {
171 return true;
174 void SetAsDefaultBrowserHandler::HandleLaunchSetDefaultBrowserFlow(
175 const base::ListValue* args) {
176 set_default_returned_ = false;
177 set_default_result_ = false;
178 default_browser_worker_->StartSetAsDefault();
181 void SetAsDefaultBrowserHandler::ConcludeInteraction(
182 MakeChromeDefaultResult interaction_result) {
183 DCHECK_CURRENTLY_ON(BrowserThread::UI);
185 if (response_delegate_)
186 response_delegate_->SetDialogInteractionResult(interaction_result);
188 WebContents* contents = web_ui()->GetWebContents();
190 if (contents) {
191 content::WebContentsDelegate* delegate = contents->GetDelegate();
192 if (delegate)
193 delegate->CloseContents(contents);
197 // A web dialog delegate implementation for when 'Make Chrome Metro' UI
198 // is displayed on a dialog.
199 class SetAsDefaultBrowserDialogImpl : public ui::WebDialogDelegate,
200 public ResponseDelegate,
201 public chrome::BrowserListObserver {
202 public:
203 SetAsDefaultBrowserDialogImpl(Profile* profile, Browser* browser);
204 virtual ~SetAsDefaultBrowserDialogImpl();
205 // Show a modal web dialog with kChromeUIMetroFlowURL page.
206 void ShowDialog();
208 protected:
209 // Overridden from WebDialogDelegate:
210 virtual ui::ModalType GetDialogModalType() const override;
211 virtual base::string16 GetDialogTitle() const override;
212 virtual GURL GetDialogContentURL() const override;
213 virtual void GetWebUIMessageHandlers(
214 std::vector<WebUIMessageHandler*>* handlers) const override;
215 virtual void GetDialogSize(gfx::Size* size) const override;
216 virtual std::string GetDialogArgs() const override;
217 virtual void OnDialogClosed(const std::string& json_retval) override;
218 virtual void OnCloseContents(WebContents* source,
219 bool* out_close_dialog) override;
220 virtual bool ShouldShowDialogTitle() const override;
221 virtual bool HandleContextMenu(
222 const content::ContextMenuParams& params) override;
224 // Overridden from ResponseDelegate:
225 virtual void SetDialogInteractionResult(MakeChromeDefaultResult result);
227 // Overridden from BrowserListObserver:
228 virtual void OnBrowserRemoved(Browser* browser) override;
230 private:
231 Profile* profile_;
232 Browser* browser_;
233 mutable bool owns_handler_;
234 base::WeakPtrFactory<ResponseDelegate> response_delegate_ptr_factory_;
235 SetAsDefaultBrowserHandler* handler_;
236 MakeChromeDefaultResult dialog_interaction_result_;
238 DISALLOW_COPY_AND_ASSIGN(SetAsDefaultBrowserDialogImpl);
241 SetAsDefaultBrowserDialogImpl::SetAsDefaultBrowserDialogImpl(Profile* profile,
242 Browser* browser)
243 : profile_(profile),
244 browser_(browser),
245 owns_handler_(true),
246 response_delegate_ptr_factory_(this),
247 handler_(new SetAsDefaultBrowserHandler(
248 response_delegate_ptr_factory_.GetWeakPtr())),
249 dialog_interaction_result_(MAKE_CHROME_DEFAULT_DECLINED) {
250 BrowserList::AddObserver(this);
253 SetAsDefaultBrowserDialogImpl::~SetAsDefaultBrowserDialogImpl() {
254 if (browser_)
255 BrowserList::RemoveObserver(this);
256 if (owns_handler_)
257 delete handler_;
260 void SetAsDefaultBrowserDialogImpl::ShowDialog() {
261 // Use a NULL parent window to make sure that the dialog will have an item
262 // in the Windows task bar. The code below will make it highlight if the
263 // dialog is not in the foreground.
264 gfx::NativeWindow native_window = chrome::ShowWebDialog(NULL, profile_, this);
265 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(
266 native_window);
267 widget->FlashFrame(true);
270 ui::ModalType SetAsDefaultBrowserDialogImpl::GetDialogModalType() const {
271 return ui::MODAL_TYPE_SYSTEM;
274 base::string16 SetAsDefaultBrowserDialogImpl::GetDialogTitle() const {
275 return l10n_util::GetStringUTF16(IDS_METRO_FLOW_TAB_TITLE);
278 GURL SetAsDefaultBrowserDialogImpl::GetDialogContentURL() const {
279 std::string url_string(chrome::kChromeUIMetroFlowURL);
280 return GURL(url_string);
283 void SetAsDefaultBrowserDialogImpl::GetWebUIMessageHandlers(
284 std::vector<WebUIMessageHandler*>* handlers) const {
285 handlers->push_back(handler_);
286 owns_handler_ = false;
289 void SetAsDefaultBrowserDialogImpl::GetDialogSize(gfx::Size* size) const {
290 PrefService* prefs = profile_->GetPrefs();
291 gfx::Font approximate_web_font(
292 prefs->GetString(prefs::kWebKitSansSerifFontFamily),
293 prefs->GetInteger(prefs::kWebKitDefaultFontSize));
295 *size = ui::GetLocalizedContentsSizeForFont(
296 IDS_METRO_FLOW_WIDTH_CHARS, IDS_METRO_FLOW_HEIGHT_LINES,
297 approximate_web_font);
300 std::string SetAsDefaultBrowserDialogImpl::GetDialogArgs() const {
301 return "[]";
304 void SetAsDefaultBrowserDialogImpl::OnDialogClosed(
305 const std::string& json_retval) {
306 // Register the user's response in UMA.
307 UMA_HISTOGRAM_ENUMERATION(kSetAsDefaultBrowserHistogram,
308 dialog_interaction_result_,
309 MAKE_CHROME_DEFAULT_MAX);
311 // If the user explicitly elected *not to* make Chrome default, we won't
312 // ask again.
313 if (dialog_interaction_result_ == MAKE_CHROME_DEFAULT_REGRETTED) {
314 PrefService* prefs = profile_->GetPrefs();
315 prefs->SetBoolean(prefs::kCheckDefaultBrowser, false);
318 // Carry on with a normal chrome session. For the purpose of surfacing this
319 // dialog the actual browser window had to remain hidden. Now it's time to
320 // show it.
321 if (browser_) {
322 BrowserWindow* window = browser_->window();
323 WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
324 window->Show();
325 if (contents)
326 contents->SetInitialFocus();
329 delete this;
332 void SetAsDefaultBrowserDialogImpl::OnCloseContents(WebContents* source,
333 bool* out_close_dialog) {
334 *out_close_dialog = true;
337 bool SetAsDefaultBrowserDialogImpl::ShouldShowDialogTitle() const {
338 return true;
341 bool SetAsDefaultBrowserDialogImpl::HandleContextMenu(
342 const content::ContextMenuParams& params) {
343 return true;
346 void SetAsDefaultBrowserDialogImpl::SetDialogInteractionResult(
347 MakeChromeDefaultResult result) {
348 dialog_interaction_result_ = result;
351 void SetAsDefaultBrowserDialogImpl::OnBrowserRemoved(Browser* browser) {
352 if (browser_ == browser) {
353 browser_ = NULL;
354 BrowserList::RemoveObserver(this);
358 } // namespace
360 SetAsDefaultBrowserUI::SetAsDefaultBrowserUI(content::WebUI* web_ui)
361 : ui::WebDialogUI(web_ui) {
362 content::WebUIDataSource::Add(
363 Profile::FromWebUI(web_ui), CreateSetAsDefaultBrowserUIHTMLSource());
366 // static
367 void SetAsDefaultBrowserUI::Show(Profile* profile, Browser* browser) {
368 DCHECK_CURRENTLY_ON(BrowserThread::UI);
369 SetAsDefaultBrowserDialogImpl* dialog =
370 new SetAsDefaultBrowserDialogImpl(profile, browser);
371 dialog->ShowDialog();