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