[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / views / download / download_danger_prompt_views.cc
blob70efbe2e21fdb53198288d32a12c422c37ee6eb7
1 // Copyright 2013 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 "base/compiler_specific.h"
6 #include "chrome/browser/download/download_danger_prompt.h"
7 #include "chrome/browser/download/download_stats.h"
8 #include "components/web_modal/web_contents_modal_dialog_host.h"
9 #include "components/web_modal/web_contents_modal_dialog_manager.h"
10 #include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/download_danger_type.h"
13 #include "content/public/browser/download_item.h"
14 #include "content/public/browser/web_contents.h"
15 #include "grit/chromium_strings.h"
16 #include "grit/generated_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/views/controls/button/label_button.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/grid_layout.h"
22 #include "ui/views/view.h"
23 #include "ui/views/widget/widget.h"
24 #include "ui/views/window/dialog_client_view.h"
25 #include "ui/views/window/dialog_delegate.h"
27 using content::BrowserThread;
28 using web_modal::WebContentsModalDialogManager;
29 using web_modal::WebContentsModalDialogManagerDelegate;
31 namespace {
33 const int kMessageWidth = 320;
34 const int kParagraphPadding = 15;
36 // Views-specific implementation of download danger prompt dialog. We use this
37 // class rather than a TabModalConfirmDialog so that we can use custom
38 // formatting on the text in the body of the dialog.
39 class DownloadDangerPromptViews : public DownloadDangerPrompt,
40 public content::DownloadItem::Observer,
41 public views::DialogDelegate {
42 public:
43 DownloadDangerPromptViews(content::DownloadItem* item,
44 content::WebContents* web_contents,
45 bool show_context,
46 const OnDone& done);
48 // DownloadDangerPrompt methods:
49 virtual void InvokeActionForTesting(Action action) OVERRIDE;
51 // views::DialogDelegate methods:
52 virtual base::string16 GetDialogButtonLabel(
53 ui::DialogButton button) const OVERRIDE;
54 virtual base::string16 GetWindowTitle() const OVERRIDE;
55 virtual void DeleteDelegate() OVERRIDE;
56 virtual ui::ModalType GetModalType() const OVERRIDE;
57 virtual bool Cancel() OVERRIDE;
58 virtual bool Accept() OVERRIDE;
59 virtual bool Close() OVERRIDE;
60 virtual views::View* GetInitiallyFocusedView() OVERRIDE;
61 virtual views::View* GetContentsView() OVERRIDE;
62 virtual views::Widget* GetWidget() OVERRIDE;
63 virtual const views::Widget* GetWidget() const OVERRIDE;
65 // content::DownloadItem::Observer:
66 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
68 private:
69 base::string16 GetAcceptButtonTitle() const;
70 base::string16 GetCancelButtonTitle() const;
71 // The message lead is separated from the main text and is bolded.
72 base::string16 GetMessageLead() const;
73 base::string16 GetMessageBody() const;
74 void RunDone(Action action);
76 content::DownloadItem* download_;
77 bool show_context_;
78 OnDone done_;
80 views::View* contents_view_;
83 DownloadDangerPromptViews::DownloadDangerPromptViews(
84 content::DownloadItem* item,
85 content::WebContents* web_contents,
86 bool show_context,
87 const OnDone& done)
88 : download_(item),
89 show_context_(show_context),
90 done_(done),
91 contents_view_(NULL) {
92 DCHECK(!done_.is_null());
93 download_->AddObserver(this);
95 contents_view_ = new views::View;
97 views::GridLayout* layout = views::GridLayout::CreatePanel(contents_view_);
98 contents_view_->SetLayoutManager(layout);
100 views::ColumnSet* column_set = layout->AddColumnSet(0);
101 column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
102 views::GridLayout::FIXED, kMessageWidth, 0);
104 const base::string16 message_lead = GetMessageLead();
106 if (!message_lead.empty()) {
107 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
108 views::Label* message_lead_label = new views::Label(
109 message_lead, rb->GetFontList(ui::ResourceBundle::BoldFont));
110 message_lead_label->SetMultiLine(true);
111 message_lead_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
112 message_lead_label->SetAllowCharacterBreak(true);
114 layout->StartRow(0, 0);
115 layout->AddView(message_lead_label);
117 layout->AddPaddingRow(0, kParagraphPadding);
120 views::Label* message_body_label = new views::Label(GetMessageBody());
121 message_body_label->SetMultiLine(true);
122 message_body_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
123 message_body_label->SetAllowCharacterBreak(true);
125 layout->StartRow(0, 0);
126 layout->AddView(message_body_label);
128 RecordOpenedDangerousConfirmDialog(download_->GetDangerType());
131 // DownloadDangerPrompt methods:
132 void DownloadDangerPromptViews::InvokeActionForTesting(Action action) {
133 switch (action) {
134 case ACCEPT:
135 Accept();
136 break;
138 case CANCEL:
139 case DISMISS:
140 Cancel();
141 break;
143 default:
144 NOTREACHED();
145 break;
149 // views::DialogDelegate methods:
150 base::string16 DownloadDangerPromptViews::GetDialogButtonLabel(
151 ui::DialogButton button) const {
152 switch (button) {
153 case ui::DIALOG_BUTTON_OK:
154 return GetAcceptButtonTitle();
156 case ui::DIALOG_BUTTON_CANCEL:
157 return GetCancelButtonTitle();
159 default:
160 return DialogDelegate::GetDialogButtonLabel(button);
164 base::string16 DownloadDangerPromptViews::GetWindowTitle() const {
165 if (show_context_)
166 return l10n_util::GetStringUTF16(IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE);
167 else
168 return l10n_util::GetStringUTF16(IDS_RESTORE_KEEP_DANGEROUS_DOWNLOAD_TITLE);
171 void DownloadDangerPromptViews::DeleteDelegate() {
172 DCHECK_CURRENTLY_ON(BrowserThread::UI);
174 delete this;
177 ui::ModalType DownloadDangerPromptViews::GetModalType() const {
178 #if defined(USE_ASH)
179 return ui::MODAL_TYPE_CHILD;
180 #else
181 return views::WidgetDelegate::GetModalType();
182 #endif
185 bool DownloadDangerPromptViews::Cancel() {
186 DCHECK_CURRENTLY_ON(BrowserThread::UI);
188 RunDone(CANCEL);
189 return true;
192 bool DownloadDangerPromptViews::Accept() {
193 DCHECK_CURRENTLY_ON(BrowserThread::UI);
195 RunDone(ACCEPT);
196 return true;
199 bool DownloadDangerPromptViews::Close() {
200 DCHECK_CURRENTLY_ON(BrowserThread::UI);
202 RunDone(DISMISS);
203 return true;
206 views::View* DownloadDangerPromptViews::GetInitiallyFocusedView() {
207 return GetDialogClientView()->cancel_button();
210 views::View* DownloadDangerPromptViews::GetContentsView() {
211 return contents_view_;
214 views::Widget* DownloadDangerPromptViews::GetWidget() {
215 return contents_view_->GetWidget();
218 const views::Widget* DownloadDangerPromptViews::GetWidget() const {
219 return contents_view_->GetWidget();
222 // content::DownloadItem::Observer:
223 void DownloadDangerPromptViews::OnDownloadUpdated(
224 content::DownloadItem* download) {
225 // If the download is nolonger dangerous (accepted externally) or the download
226 // is in a terminal state, then the download danger prompt is no longer
227 // necessary.
228 if (!download_->IsDangerous() || download_->IsDone()) {
229 RunDone(DISMISS);
230 Cancel();
234 base::string16 DownloadDangerPromptViews::GetAcceptButtonTitle() const {
235 if (show_context_)
236 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD);
237 switch (download_->GetDangerType()) {
238 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
239 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
240 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
241 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD_AGAIN_MALICIOUS);
243 default:
244 return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD_AGAIN);
248 base::string16 DownloadDangerPromptViews::GetCancelButtonTitle() const {
249 if (show_context_)
250 return l10n_util::GetStringUTF16(IDS_CANCEL);
251 switch (download_->GetDangerType()) {
252 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
253 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
254 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
255 return l10n_util::GetStringUTF16(IDS_CONFIRM_CANCEL_AGAIN_MALICIOUS);
257 default:
258 return l10n_util::GetStringUTF16(IDS_CANCEL);
262 base::string16 DownloadDangerPromptViews::GetMessageLead() const {
263 if (!show_context_) {
264 switch (download_->GetDangerType()) {
265 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
266 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
267 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
268 return l10n_util::GetStringUTF16(
269 IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_LEAD);
271 default:
272 break;
276 return base::string16();
279 base::string16 DownloadDangerPromptViews::GetMessageBody() const {
280 if (show_context_) {
281 switch (download_->GetDangerType()) {
282 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: {
283 return l10n_util::GetStringFUTF16(
284 IDS_PROMPT_DANGEROUS_DOWNLOAD,
285 download_->GetFileNameToReportUser().LossyDisplayName());
287 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: // Fall through
288 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
289 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
290 return l10n_util::GetStringFUTF16(
291 IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT,
292 download_->GetFileNameToReportUser().LossyDisplayName());
294 case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: {
295 return l10n_util::GetStringFUTF16(
296 IDS_PROMPT_UNCOMMON_DOWNLOAD_CONTENT,
297 download_->GetFileNameToReportUser().LossyDisplayName());
299 case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
300 return l10n_util::GetStringFUTF16(
301 IDS_PROMPT_DOWNLOAD_CHANGES_SETTINGS,
302 download_->GetFileNameToReportUser().LossyDisplayName());
304 case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
305 case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
306 case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
307 case content::DOWNLOAD_DANGER_TYPE_MAX: {
308 break;
311 } else {
312 switch (download_->GetDangerType()) {
313 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
314 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
315 case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
316 return l10n_util::GetStringUTF16(
317 IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_BODY);
319 default: {
320 return l10n_util::GetStringUTF16(
321 IDS_PROMPT_CONFIRM_KEEP_DANGEROUS_DOWNLOAD);
325 NOTREACHED();
326 return base::string16();
329 void DownloadDangerPromptViews::RunDone(Action action) {
330 // Invoking the callback can cause the download item state to change or cause
331 // the window to close, and |callback| refers to a member variable.
332 OnDone done = done_;
333 done_.Reset();
334 if (download_ != NULL) {
335 download_->RemoveObserver(this);
336 download_ = NULL;
338 if (!done.is_null())
339 done.Run(action);
342 } // namespace
344 DownloadDangerPrompt* DownloadDangerPrompt::Create(
345 content::DownloadItem* item,
346 content::WebContents* web_contents,
347 bool show_context,
348 const OnDone& done) {
349 DownloadDangerPromptViews* download_danger_prompt =
350 new DownloadDangerPromptViews(item, web_contents, show_context, done);
352 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
353 WebContentsModalDialogManager::FromWebContents(web_contents);
354 WebContentsModalDialogManagerDelegate* modal_delegate =
355 web_contents_modal_dialog_manager->delegate();
356 CHECK(modal_delegate);
357 views::Widget* dialog = views::Widget::CreateWindowAsFramelessChild(
358 download_danger_prompt,
359 modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
360 web_contents_modal_dialog_manager->ShowModalDialog(
361 dialog->GetNativeView());
363 return download_danger_prompt;