Index: chrome/browser/download/download_danger_prompt.cc |
diff --git a/chrome/browser/download/download_danger_prompt.cc b/chrome/browser/download/download_danger_prompt.cc |
index bdd75cc4d58c2eb7c6cc8cabcdf19b80154d5bef..924abe5caa059c634b1fb9abdbe07e411d8d9da8 100644 |
--- a/chrome/browser/download/download_danger_prompt.cc |
+++ b/chrome/browser/download/download_danger_prompt.cc |
@@ -8,6 +8,7 @@ |
#include "chrome/browser/download/chrome_download_manager_delegate.h" |
#include "chrome/browser/ui/tab_modal_confirm_dialog.h" |
#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h" |
+#include "chrome/common/chrome_notification_types.h" |
#include "content/public/browser/download_danger_type.h" |
#include "content/public/browser/download_item.h" |
#include "grit/generated_resources.h" |
@@ -25,7 +26,8 @@ class DownloadDangerPromptImpl |
content::WebContents* web_contents, |
bool show_context, |
const base::Closure& accepted, |
- const base::Closure& canceled); |
+ const base::Closure& canceled, |
+ const base::Closure& destroyed); |
virtual ~DownloadDangerPromptImpl(); |
// DownloadDangerPrompt |
@@ -43,6 +45,12 @@ class DownloadDangerPromptImpl |
virtual void OnAccepted() OVERRIDE; |
virtual void OnCanceled() OVERRIDE; |
+ // content::NotificationObserver implementation. |
+ virtual void Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) OVERRIDE; |
+ |
// Runs |callback|. PrepareToClose() is called beforehand. Doing so prevents |
// this object from responding to state changes in |download_| that might |
// result from invoking the callback. |callback| must refer to either |
@@ -57,6 +65,7 @@ class DownloadDangerPromptImpl |
bool show_context_; |
base::Closure accepted_; |
base::Closure canceled_; |
+ base::Closure destroyed_; |
DISALLOW_COPY_AND_ASSIGN(DownloadDangerPromptImpl); |
}; |
@@ -66,12 +75,14 @@ DownloadDangerPromptImpl::DownloadDangerPromptImpl( |
content::WebContents* web_contents, |
bool show_context, |
const base::Closure& accepted, |
- const base::Closure& canceled) |
+ const base::Closure& canceled, |
+ const base::Closure& destroyed) |
: TabModalConfirmDialogDelegate(web_contents), |
download_(download), |
show_context_(show_context), |
accepted_(accepted), |
- canceled_(canceled) { |
+ canceled_(canceled), |
+ destroyed_(destroyed) { |
DCHECK(!accepted_.is_null()); |
// canceled_ is allowed to be null. |
DCHECK(download_); |
@@ -81,7 +92,11 @@ DownloadDangerPromptImpl::DownloadDangerPromptImpl( |
DownloadDangerPromptImpl::~DownloadDangerPromptImpl() { |
// |this| might be deleted without invoking any callbacks. E.g. pressing Esc |
// on GTK or if the user navigates away from the page showing the prompt. |
+ base::Closure destroyed = destroyed_; |
+ destroyed_.Reset(); |
PrepareToClose(); |
+ if (!destroyed.is_null()) |
+ destroyed.Run(); |
} |
void DownloadDangerPromptImpl::InvokeActionForTesting(Action action) { |
@@ -96,8 +111,11 @@ void DownloadDangerPromptImpl::OnDownloadUpdated( |
// If the download is nolonger dangerous (accepted externally) or the download |
// is in a terminal state, then the download danger prompt is no longer |
// necessary. |
- if (!download->IsDangerous() || download->IsDone()) |
+ if (!download->IsDangerous() || download->IsDone()) { |
+ accepted_.Reset(); |
+ canceled_.Reset(); |
Cancel(); |
+ } |
} |
void DownloadDangerPromptImpl::OnDownloadOpened( |
@@ -146,6 +164,21 @@ void DownloadDangerPromptImpl::OnCanceled() { |
RunCallback(canceled_); |
} |
+void DownloadDangerPromptImpl::Observe( |
+ int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ // Same logic as TabModalConfirmDialogDelegate::Observe, but don't run |
+ // canceled_. Just run destroyed_. |
+ if (type == content::NOTIFICATION_LOAD_START || |
+ type == chrome::NOTIFICATION_TAB_CLOSING) { |
+ PrepareToClose(); |
+ Cancel(); |
+ } else { |
+ NOTREACHED(); |
+ } |
+} |
+ |
void DownloadDangerPromptImpl::RunCallback(const base::Closure& callback) { |
// Invoking the callback can cause the download item state to change or cause |
// the constrained window to close, and |callback| refers to a member |
@@ -173,9 +206,10 @@ DownloadDangerPrompt* DownloadDangerPrompt::Create( |
content::WebContents* web_contents, |
bool show_context, |
const base::Closure& accepted, |
- const base::Closure& canceled) { |
+ const base::Closure& canceled, |
+ const base::Closure& destroyed) { |
DownloadDangerPromptImpl* prompt = new DownloadDangerPromptImpl( |
- item, web_contents, show_context, accepted, canceled); |
+ item, web_contents, show_context, accepted, canceled, destroyed); |
// |prompt| will be deleted when the dialog is done. |
TabModalConfirmDialog::Create(prompt, web_contents); |
return prompt; |