download_danger_prompt.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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.
4
5#include "chrome/browser/download/download_danger_prompt.h"
6
7#include "base/bind.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/browser/chrome_notification_types.h"
10#include "chrome/browser/download/chrome_download_manager_delegate.h"
11#include "chrome/browser/download/download_stats.h"
12#include "chrome/browser/ui/tab_modal_confirm_dialog.h"
13#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
14#include "content/public/browser/download_danger_type.h"
15#include "content/public/browser/download_item.h"
16#include "grit/chromium_strings.h"
17#include "grit/generated_resources.h"
18#include "ui/base/l10n/l10n_util.h"
19
20namespace {
21
22// TODO(wittman): Create a native web contents modal dialog implementation of
23// this dialog for non-Views platforms, to support bold formatting of the
24// message lead.
25
26// Implements DownloadDangerPrompt using a TabModalConfirmDialog.
27class DownloadDangerPromptImpl : public DownloadDangerPrompt,
28                                 public content::DownloadItem::Observer,
29                                 public TabModalConfirmDialogDelegate {
30 public:
31  DownloadDangerPromptImpl(content::DownloadItem* item,
32                           content::WebContents* web_contents,
33                           bool show_context,
34                           const OnDone& done);
35  virtual ~DownloadDangerPromptImpl();
36
37  // DownloadDangerPrompt:
38  virtual void InvokeActionForTesting(Action action) OVERRIDE;
39
40 private:
41  // content::DownloadItem::Observer:
42  virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
43
44  // TabModalConfirmDialogDelegate:
45  virtual base::string16 GetTitle() OVERRIDE;
46  virtual base::string16 GetMessage() OVERRIDE;
47  virtual base::string16 GetAcceptButtonTitle() OVERRIDE;
48  virtual base::string16 GetCancelButtonTitle() OVERRIDE;
49  virtual void OnAccepted() OVERRIDE;
50  virtual void OnCanceled() OVERRIDE;
51  virtual void OnClosed() OVERRIDE;
52
53  void RunDone(Action action);
54
55  content::DownloadItem* download_;
56  bool show_context_;
57  OnDone done_;
58
59  DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptImpl);
60};
61
62DownloadDangerPromptImpl::DownloadDangerPromptImpl(
63    content::DownloadItem* download,
64    content::WebContents* web_contents,
65    bool show_context,
66    const OnDone& done)
67    : TabModalConfirmDialogDelegate(web_contents),
68      download_(download),
69      show_context_(show_context),
70      done_(done) {
71  DCHECK(!done_.is_null());
72  download_->AddObserver(this);
73  RecordOpenedDangerousConfirmDialog(download_->GetDangerType());
74}
75
76DownloadDangerPromptImpl::~DownloadDangerPromptImpl() {
77  // |this| might be deleted without invoking any callbacks. E.g. pressing Esc
78  // on GTK or if the user navigates away from the page showing the prompt.
79  RunDone(DISMISS);
80}
81
82void DownloadDangerPromptImpl::InvokeActionForTesting(Action action) {
83  switch (action) {
84    case ACCEPT: Accept(); break;
85    case CANCEL: Cancel(); break;
86    case DISMISS:
87      RunDone(DISMISS);
88      Cancel();
89      break;
90  }
91}
92
93void DownloadDangerPromptImpl::OnDownloadUpdated(
94    content::DownloadItem* download) {
95  // If the download is nolonger dangerous (accepted externally) or the download
96  // is in a terminal state, then the download danger prompt is no longer
97  // necessary.
98  if (!download->IsDangerous() || download->IsDone()) {
99    RunDone(DISMISS);
100    Cancel();
101  }
102}
103
104string16 DownloadDangerPromptImpl::GetTitle() {
105  if (show_context_)
106    return l10n_util::GetStringUTF16(IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE);
107  switch (download_->GetDangerType()) {
108    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
109    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
110    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
111    case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
112      return l10n_util::GetStringUTF16(
113          IDS_RESTORE_KEEP_DANGEROUS_DOWNLOAD_TITLE);
114    }
115    default: {
116      return l10n_util::GetStringUTF16(
117          IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE);
118    }
119  }
120}
121
122string16 DownloadDangerPromptImpl::GetMessage() {
123  if (show_context_) {
124    switch (download_->GetDangerType()) {
125      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: {
126        return l10n_util::GetStringFUTF16(
127            IDS_PROMPT_DANGEROUS_DOWNLOAD,
128            download_->GetFileNameToReportUser().LossyDisplayName());
129      }
130      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: // Fall through
131      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
132      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
133        return l10n_util::GetStringFUTF16(
134            IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT,
135            download_->GetFileNameToReportUser().LossyDisplayName());
136      }
137      case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: {
138        return l10n_util::GetStringFUTF16(
139            IDS_PROMPT_UNCOMMON_DOWNLOAD_CONTENT,
140            download_->GetFileNameToReportUser().LossyDisplayName());
141      }
142      case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
143        return l10n_util::GetStringFUTF16(
144            IDS_PROMPT_DOWNLOAD_CHANGES_SETTINGS,
145            download_->GetFileNameToReportUser().LossyDisplayName());
146      }
147      case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
148      case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
149      case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
150      case content::DOWNLOAD_DANGER_TYPE_MAX: {
151        break;
152      }
153    }
154  } else {
155    switch (download_->GetDangerType()) {
156      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
157      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
158      case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
159        return l10n_util::GetStringUTF16(
160            IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_LEAD) +
161            ASCIIToUTF16("\n\n") +
162            l10n_util::GetStringUTF16(
163                IDS_PROMPT_CONFIRM_KEEP_MALICIOUS_DOWNLOAD_BODY);
164      }
165      default: {
166        return l10n_util::GetStringUTF16(
167            IDS_PROMPT_CONFIRM_KEEP_DANGEROUS_DOWNLOAD);
168      }
169    }
170  }
171  NOTREACHED();
172  return base::string16();
173}
174
175string16 DownloadDangerPromptImpl::GetAcceptButtonTitle() {
176  if (show_context_)
177    return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD);
178  switch (download_->GetDangerType()) {
179    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
180    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
181    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
182    case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
183      return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD_AGAIN_MALICIOUS);
184    }
185    default:
186      return l10n_util::GetStringUTF16(IDS_CONFIRM_DOWNLOAD_AGAIN);
187  }
188}
189
190string16 DownloadDangerPromptImpl::GetCancelButtonTitle() {
191  if (show_context_)
192    return l10n_util::GetStringUTF16(IDS_CANCEL);
193  switch (download_->GetDangerType()) {
194    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
195    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
196    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
197    case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
198      return l10n_util::GetStringUTF16(IDS_CONFIRM_CANCEL_AGAIN_MALICIOUS);
199    }
200    default:
201      return l10n_util::GetStringUTF16(IDS_CANCEL);
202  }
203}
204
205void DownloadDangerPromptImpl::OnAccepted() {
206  RunDone(ACCEPT);
207}
208
209void DownloadDangerPromptImpl::OnCanceled() {
210  RunDone(CANCEL);
211}
212
213void DownloadDangerPromptImpl::OnClosed() {
214  RunDone(DISMISS);
215}
216
217void DownloadDangerPromptImpl::RunDone(Action action) {
218  // Invoking the callback can cause the download item state to change or cause
219  // the constrained window to close, and |callback| refers to a member
220  // variable.
221  OnDone done = done_;
222  done_.Reset();
223  if (download_ != NULL) {
224    download_->RemoveObserver(this);
225    download_ = NULL;
226  }
227  if (!done.is_null())
228    done.Run(action);
229}
230
231}  // namespace
232
233#if !(defined(OS_WIN) || defined(USE_AURA))
234// static
235DownloadDangerPrompt* DownloadDangerPrompt::Create(
236    content::DownloadItem* item,
237    content::WebContents* web_contents,
238    bool show_context,
239    const OnDone& done) {
240  DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl(
241      item, web_contents, show_context, done);
242  // |prompt| will be deleted when the dialog is done.
243  TabModalConfirmDialog::Create(prompt, web_contents);
244  return prompt;
245}
246#endif
247