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