download_danger_prompt.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
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/metrics/field_trial.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_util.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// Implements DownloadDangerPrompt using a TabModalConfirmDialog.
23class DownloadDangerPromptImpl
24  : public DownloadDangerPrompt,
25    public content::DownloadItem::Observer,
26    public TabModalConfirmDialogDelegate {
27 public:
28  DownloadDangerPromptImpl(content::DownloadItem* item,
29                           content::WebContents* web_contents,
30                           bool show_context,
31                           const OnDone& done);
32  virtual ~DownloadDangerPromptImpl();
33
34  // DownloadDangerPrompt
35  virtual void InvokeActionForTesting(Action action) OVERRIDE;
36
37 private:
38  // content::DownloadItem::Observer
39  virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE;
40
41  // TabModalConfirmDialogDelegate
42  virtual string16 GetTitle() OVERRIDE;
43  virtual string16 GetMessage() OVERRIDE;
44  virtual string16 GetAcceptButtonTitle() OVERRIDE;
45  virtual void OnAccepted() OVERRIDE;
46  virtual void OnCanceled() OVERRIDE;
47  virtual void OnClosed() OVERRIDE;
48
49  void RunDone(Action action);
50
51  content::DownloadItem* download_;
52  bool show_context_;
53  OnDone done_;
54
55  DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptImpl);
56};
57
58DownloadDangerPromptImpl::DownloadDangerPromptImpl(
59    content::DownloadItem* download,
60    content::WebContents* web_contents,
61    bool show_context,
62    const OnDone& done)
63    : TabModalConfirmDialogDelegate(web_contents),
64      download_(download),
65      show_context_(show_context),
66      done_(done) {
67  DCHECK(!done_.is_null());
68  download_->AddObserver(this);
69}
70
71DownloadDangerPromptImpl::~DownloadDangerPromptImpl() {
72  // |this| might be deleted without invoking any callbacks. E.g. pressing Esc
73  // on GTK or if the user navigates away from the page showing the prompt.
74  RunDone(DISMISS);
75}
76
77void DownloadDangerPromptImpl::InvokeActionForTesting(Action action) {
78  switch (action) {
79    case ACCEPT: Accept(); break;
80    case CANCEL: Cancel(); break;
81    case DISMISS:
82      RunDone(DISMISS);
83      Cancel();
84      break;
85  }
86}
87
88void DownloadDangerPromptImpl::OnDownloadUpdated(
89    content::DownloadItem* download) {
90  // If the download is nolonger dangerous (accepted externally) or the download
91  // is in a terminal state, then the download danger prompt is no longer
92  // necessary.
93  if (!download->IsDangerous() || download->IsDone()) {
94    RunDone(DISMISS);
95    Cancel();
96  }
97}
98
99string16 DownloadDangerPromptImpl::GetTitle() {
100  return l10n_util::GetStringUTF16(IDS_CONFIRM_KEEP_DANGEROUS_DOWNLOAD_TITLE);
101}
102
103string16 DownloadDangerPromptImpl::GetMessage() {
104  if (!show_context_)
105    return l10n_util::GetStringUTF16(
106        IDS_PROMPT_CONFIRM_KEEP_DANGEROUS_DOWNLOAD);
107  switch (download_->GetDangerType()) {
108    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE: {
109      return l10n_util::GetStringFUTF16(
110          IDS_PROMPT_DANGEROUS_DOWNLOAD,
111          download_->GetFileNameToReportUser().LossyDisplayName());
112    }
113    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL: // Fall through
114    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
115    case content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST: {
116      std::string trial_condition =
117          base::FieldTrialList::FindFullName(download_util::kFinchTrialName);
118      if (trial_condition.empty()) {
119        return l10n_util::GetStringFUTF16(
120            IDS_PROMPT_MALICIOUS_DOWNLOAD_CONTENT,
121            download_->GetFileNameToReportUser().LossyDisplayName());
122      }
123      return download_util::AssembleMalwareFinchString(
124          trial_condition,
125          download_->GetFileNameToReportUser().LossyDisplayName());
126    }
127    case content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: {
128      return l10n_util::GetStringFUTF16(
129          IDS_PROMPT_UNCOMMON_DOWNLOAD_CONTENT,
130          download_->GetFileNameToReportUser().LossyDisplayName());
131    }
132    case content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED: {
133      return l10n_util::GetStringFUTF16(
134          IDS_PROMPT_DOWNLOAD_CHANGES_SEARCH_SETTINGS,
135          download_->GetFileNameToReportUser().LossyDisplayName());
136    }
137    case content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS:
138    case content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT:
139    case content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED:
140    case content::DOWNLOAD_DANGER_TYPE_MAX: {
141      break;
142    }
143  }
144  NOTREACHED();
145  return string16();
146}
147
148string16 DownloadDangerPromptImpl::GetAcceptButtonTitle() {
149  return l10n_util::GetStringUTF16(
150      show_context_ ? IDS_CONFIRM_DOWNLOAD : IDS_CONFIRM_DOWNLOAD_AGAIN);
151}
152
153void DownloadDangerPromptImpl::OnAccepted() {
154  RunDone(ACCEPT);
155}
156
157void DownloadDangerPromptImpl::OnCanceled() {
158  RunDone(CANCEL);
159}
160
161void DownloadDangerPromptImpl::OnClosed() {
162  RunDone(CANCEL);
163}
164
165void DownloadDangerPromptImpl::RunDone(Action action) {
166  // Invoking the callback can cause the download item state to change or cause
167  // the constrained window to close, and |callback| refers to a member
168  // variable.
169  OnDone done = done_;
170  done_.Reset();
171  if (download_ != NULL) {
172    download_->RemoveObserver(this);
173    download_ = NULL;
174  }
175  if (!done.is_null())
176    done.Run(action);
177}
178
179}  // namespace
180
181// static
182DownloadDangerPrompt* DownloadDangerPrompt::Create(
183    content::DownloadItem* item,
184    content::WebContents* web_contents,
185    bool show_context,
186    const OnDone& done) {
187  DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl(
188      item, web_contents, show_context, done);
189  // |prompt| will be deleted when the dialog is done.
190  TabModalConfirmDialog::Create(prompt, web_contents);
191  return prompt;
192}
193