| 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;
|
|
|