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