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