summaryrefslogtreecommitdiffstats
path: root/chrome/browser/download
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-14 20:12:50 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-14 20:12:50 +0000
commit58db2f88917448f794deeee45868137d9098339a (patch)
tree0aa9feba219c093223542830c3e9951aa8f63ec1 /chrome/browser/download
parent66814bb0eb9fd82cb6acd58ddc9292555bd98322 (diff)
downloadchromium_src-58db2f88917448f794deeee45868137d9098339a.zip
chromium_src-58db2f88917448f794deeee45868137d9098339a.tar.gz
chromium_src-58db2f88917448f794deeee45868137d9098339a.tar.bz2
Make the multiple download request dialog an infobar.
The icon is a placeholder until Glen makes a pretty one. BUG=24047 TEST=go to skypher.com/SkyLined/Repro/Chrome/carpet bombing/repro.html allow, deny, closing infobar, and closing tab all work as expected Review URL: http://codereview.chromium.org/275011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29006 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/download')
-rw-r--r--chrome/browser/download/download_request_dialog_delegate.h57
-rw-r--r--chrome/browser/download/download_request_dialog_delegate_win.cc60
-rw-r--r--chrome/browser/download/download_request_dialog_delegate_win.h45
-rw-r--r--chrome/browser/download/download_request_infobar_delegate.cc65
-rw-r--r--chrome/browser/download/download_request_infobar_delegate.h50
-rw-r--r--chrome/browser/download/download_request_infobar_delegate_unittest.cc66
-rw-r--r--chrome/browser/download/download_request_manager.cc28
-rw-r--r--chrome/browser/download/download_request_manager.h26
8 files changed, 209 insertions, 188 deletions
diff --git a/chrome/browser/download/download_request_dialog_delegate.h b/chrome/browser/download/download_request_dialog_delegate.h
deleted file mode 100644
index af4ad20..0000000
--- a/chrome/browser/download/download_request_dialog_delegate.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_DIALOG_DELEGATE_H_
-#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_DIALOG_DELEGATE_H_
-
-#include "base/basictypes.h"
-
-#include "chrome/browser/download/download_request_manager.h"
-
-// DownloadRequestDialogDelegate is the dialog implementation used to prompt the
-// the user as to whether they want to allow multiple downloads.
-// DownloadRequestDialogDelegate delegates the allow/cancel methods to the
-// TabDownloadState.
-//
-// TabDownloadState does not directly act as a dialog delegate because
-// the dialog may outlive the TabDownloadState object.
-class DownloadRequestDialogDelegate {
- public:
- // This factory method constructs a DownloadRequestDialogDelegate in a
- // platform-specific way.
- static DownloadRequestDialogDelegate* Create(TabContents* tab,
- DownloadRequestManager::TabDownloadState* host);
-
- void set_host(DownloadRequestManager::TabDownloadState* host) {
- host_ = host;
- }
-
- // Closes the prompt.
- virtual void CloseWindow() = 0;
-
- protected:
- explicit DownloadRequestDialogDelegate(
- DownloadRequestManager::TabDownloadState* host) : host_(host) { }
-
- virtual ~DownloadRequestDialogDelegate() { }
-
- virtual bool DoCancel() {
- if (host_)
- host_->Cancel();
- return true;
- }
-
- virtual bool DoAccept() {
- if (host_)
- host_->Accept();
- return true;
- }
-
- // The TabDownloadState we're displaying the dialog for. May be null.
- DownloadRequestManager::TabDownloadState* host_;
-
- DISALLOW_COPY_AND_ASSIGN(DownloadRequestDialogDelegate);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_DIALOG_DELEGATE_H_
diff --git a/chrome/browser/download/download_request_dialog_delegate_win.cc b/chrome/browser/download/download_request_dialog_delegate_win.cc
deleted file mode 100644
index 6129af6..0000000
--- a/chrome/browser/download/download_request_dialog_delegate_win.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/download/download_request_dialog_delegate_win.h"
-
-#include "app/l10n_util.h"
-#include "app/message_box_flags.h"
-#include "chrome/browser/tab_contents/constrained_window.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "grit/generated_resources.h"
-#include "views/controls/message_box_view.h"
-
-// static
-DownloadRequestDialogDelegate* DownloadRequestDialogDelegate::Create(
- TabContents* tab,
- DownloadRequestManager::TabDownloadState* host) {
- return new DownloadRequestDialogDelegateWin(tab, host);
-}
-
-DownloadRequestDialogDelegateWin::DownloadRequestDialogDelegateWin(
- TabContents* tab,
- DownloadRequestManager::TabDownloadState* host)
- : DownloadRequestDialogDelegate(host) {
- message_view_ = new MessageBoxView(
- MessageBoxFlags::kIsConfirmMessageBox,
- l10n_util::GetString(IDS_MULTI_DOWNLOAD_WARNING),
- std::wstring());
- window_ = tab->CreateConstrainedDialog(this);
-}
-
-void DownloadRequestDialogDelegateWin::CloseWindow() {
- window_->CloseConstrainedWindow();
-}
-
-bool DownloadRequestDialogDelegateWin::Cancel() {
- return DoCancel();
-}
-
-bool DownloadRequestDialogDelegateWin::Accept() {
- return DoAccept();
-}
-
-views::View* DownloadRequestDialogDelegateWin::GetContentsView() {
- return message_view_;
-}
-
-std::wstring DownloadRequestDialogDelegateWin::GetDialogButtonLabel(
- MessageBoxFlags::DialogButton button) const {
- if (button == MessageBoxFlags::DIALOGBUTTON_OK)
- return l10n_util::GetString(IDS_MULTI_DOWNLOAD_WARNING_ALLOW);
- if (button == MessageBoxFlags::DIALOGBUTTON_CANCEL)
- return l10n_util::GetString(IDS_MULTI_DOWNLOAD_WARNING_DENY);
- return std::wstring();
-}
-
-void DownloadRequestDialogDelegateWin::DeleteDelegate() {
- DCHECK(!host_);
- delete this;
-}
diff --git a/chrome/browser/download/download_request_dialog_delegate_win.h b/chrome/browser/download/download_request_dialog_delegate_win.h
deleted file mode 100644
index 387dce7..0000000
--- a/chrome/browser/download/download_request_dialog_delegate_win.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_DIALOG_DELEGATE_WIN_H_
-#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_DIALOG_DELEGATE_WIN_H_
-
-#include "base/basictypes.h"
-
-#include "chrome/browser/download/download_request_dialog_delegate.h"
-#include "chrome/browser/download/download_request_manager.h"
-#include "views/window/dialog_delegate.h"
-
-class ConstrainedWindow;
-class MessageBoxView;
-class TabContents;
-
-class DownloadRequestDialogDelegateWin : public DownloadRequestDialogDelegate,
- public views::DialogDelegate {
- public:
- DownloadRequestDialogDelegateWin(TabContents* tab,
- DownloadRequestManager::TabDownloadState* host);
-
- private:
- // DownloadRequestDialogDelegate methods.
- virtual void CloseWindow();
- // DialogDelegate methods.
- virtual bool Cancel();
- virtual bool Accept();
- virtual views::View* GetContentsView();
- virtual std::wstring GetDialogButtonLabel(
- MessageBoxFlags::DialogButton button) const;
- virtual int GetDefaultDialogButton() const {
- return MessageBoxFlags::DIALOGBUTTON_CANCEL;
- }
- virtual void DeleteDelegate();
-
- MessageBoxView* message_view_;
-
- ConstrainedWindow* window_;
-
- DISALLOW_COPY_AND_ASSIGN(DownloadRequestDialogDelegateWin);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_DIALOG_DELEGATE_WIN_H_
diff --git a/chrome/browser/download/download_request_infobar_delegate.cc b/chrome/browser/download/download_request_infobar_delegate.cc
new file mode 100644
index 0000000..3a6aa5d
--- /dev/null
+++ b/chrome/browser/download/download_request_infobar_delegate.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/download/download_request_infobar_delegate.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+
+DownloadRequestInfoBarDelegate::DownloadRequestInfoBarDelegate(TabContents* tab,
+ DownloadRequestManager::TabDownloadState* host)
+ : ConfirmInfoBarDelegate(tab),
+ host_(host) {
+ if (tab)
+ tab->AddInfoBar(this);
+}
+
+DownloadRequestInfoBarDelegate::~DownloadRequestInfoBarDelegate() {
+}
+
+void DownloadRequestInfoBarDelegate::InfoBarClosed() {
+ Cancel();
+ // This will delete us.
+ ConfirmInfoBarDelegate::InfoBarClosed();
+}
+
+std::wstring DownloadRequestInfoBarDelegate::GetMessageText() const {
+ return l10n_util::GetString(IDS_MULTI_DOWNLOAD_WARNING);
+}
+
+SkBitmap* DownloadRequestInfoBarDelegate::GetIcon() const {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ IDR_INFOBAR_MULTIPLE_DOWNLOADS);
+}
+
+int DownloadRequestInfoBarDelegate::GetButtons() const {
+ return BUTTON_OK | BUTTON_CANCEL;
+}
+
+std::wstring DownloadRequestInfoBarDelegate::GetButtonLabel(
+ ConfirmInfoBarDelegate::InfoBarButton button) const {
+ if (button == BUTTON_OK)
+ return l10n_util::GetString(IDS_MULTI_DOWNLOAD_WARNING_ALLOW);
+ else
+ return l10n_util::GetString(IDS_MULTI_DOWNLOAD_WARNING_DENY);
+}
+
+bool DownloadRequestInfoBarDelegate::Accept() {
+ if (host_) {
+ host_->Accept();
+ host_ = NULL;
+ }
+ return true;
+}
+
+bool DownloadRequestInfoBarDelegate::Cancel() {
+ if (host_) {
+ host_->Cancel();
+ host_ = NULL;
+ }
+ return true;
+}
diff --git a/chrome/browser/download/download_request_infobar_delegate.h b/chrome/browser/download/download_request_infobar_delegate.h
new file mode 100644
index 0000000..112c2e2
--- /dev/null
+++ b/chrome/browser/download/download_request_infobar_delegate.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_INFOBAR_DELEGATE_H_
+#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_INFOBAR_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "chrome/browser/download/download_request_manager.h"
+#include "chrome/browser/tab_contents/infobar_delegate.h"
+
+class TabContents;
+
+// An infobar delegate that presents the user with a choice to allow or deny
+// multiple downloads from the same site. This confirmation step protects
+// against "carpet-bombing", where a malicious site forces multiple downloads
+// on an unsuspecting user.
+class DownloadRequestInfoBarDelegate : public ConfirmInfoBarDelegate {
+ public:
+ DownloadRequestInfoBarDelegate(
+ TabContents* tab, DownloadRequestManager::TabDownloadState* host);
+
+ virtual ~DownloadRequestInfoBarDelegate();
+
+ void set_host(DownloadRequestManager::TabDownloadState* host) {
+ host_ = host;
+ }
+
+ virtual void InfoBarClosed();
+
+ virtual std::wstring GetMessageText() const;
+
+ virtual SkBitmap* GetIcon() const;
+
+ virtual int GetButtons() const;
+
+ virtual std::wstring GetButtonLabel(
+ ConfirmInfoBarDelegate::InfoBarButton button) const;
+
+ virtual bool Accept();
+
+ virtual bool Cancel();
+
+ private:
+ DownloadRequestManager::TabDownloadState* host_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadRequestInfoBarDelegate);
+};
+
+#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/download/download_request_infobar_delegate_unittest.cc b/chrome/browser/download/download_request_infobar_delegate_unittest.cc
new file mode 100644
index 0000000..663f8b7
--- /dev/null
+++ b/chrome/browser/download/download_request_infobar_delegate_unittest.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/download/download_request_infobar_delegate.h"
+#include "chrome/browser/download/download_request_manager.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class MockTabDownloadState : public DownloadRequestManager::TabDownloadState {
+ public:
+ MockTabDownloadState() : responded_(false), accepted_(false) {
+ }
+
+ virtual ~MockTabDownloadState() {
+ EXPECT_TRUE(responded_);
+ }
+
+ virtual void Accept() {
+ EXPECT_FALSE(responded_);
+ responded_ = true;
+ accepted_ = true;
+ }
+
+ virtual void Cancel() {
+ EXPECT_FALSE(responded_);
+ responded_ = true;
+ accepted_ = false;
+ }
+
+ bool responded() {
+ return responded_;
+ }
+
+ bool accepted() {
+ return responded_ && accepted_;
+ }
+
+ private:
+ // True if we have gotten some sort of response.
+ bool responded_;
+
+ // True if we have gotten a Accept response. Meaningless if |responded_| is
+ // not true.
+ bool accepted_;
+};
+
+TEST(DownloadRequestInfobar, AcceptTest) {
+ MockTabDownloadState state;
+ DownloadRequestInfoBarDelegate infobar(NULL, &state);
+ infobar.Accept();
+ EXPECT_TRUE(state.accepted());
+}
+
+TEST(DownloadRequestInfobar, CancelTest) {
+ MockTabDownloadState state;
+ DownloadRequestInfoBarDelegate infobar(NULL, &state);
+ infobar.Cancel();
+ EXPECT_FALSE(state.accepted());
+}
+
+TEST(DownloadRequestInfobar, CloseTest) {
+ MockTabDownloadState state;
+ DownloadRequestInfoBarDelegate infobar(NULL, &state);
+ infobar.InfoBarClosed();
+ EXPECT_FALSE(state.accepted());
+}
diff --git a/chrome/browser/download/download_request_manager.cc b/chrome/browser/download/download_request_manager.cc
index 83811e2..98a20ff 100644
--- a/chrome/browser/download/download_request_manager.cc
+++ b/chrome/browser/download/download_request_manager.cc
@@ -6,7 +6,7 @@
#include "base/message_loop.h"
#include "base/thread.h"
-#include "chrome/browser/download/download_request_dialog_delegate.h"
+#include "chrome/browser/download/download_request_infobar_delegate.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
@@ -23,7 +23,7 @@ DownloadRequestManager::TabDownloadState::TabDownloadState(
: host_(host),
controller_(controller),
status_(DownloadRequestManager::ALLOW_ONE_DOWNLOAD),
- dialog_delegate_(NULL) {
+ infobar_(NULL) {
Source<NavigationController> notification_source(controller);
registrar_.Add(this, NotificationType::NAV_ENTRY_PENDING,
notification_source);
@@ -39,8 +39,8 @@ DownloadRequestManager::TabDownloadState::~TabDownloadState() {
// We should only be destroyed after the callbacks have been notified.
DCHECK(callbacks_.empty());
- // And we should have closed the message box.
- DCHECK(!dialog_delegate_);
+ // And we should have closed the infobar.
+ DCHECK(!infobar_);
}
void DownloadRequestManager::TabDownloadState::OnUserGesture() {
@@ -69,7 +69,7 @@ void DownloadRequestManager::TabDownloadState::PromptUserForDownload(
if (DownloadRequestManager::delegate_) {
NotifyCallbacks(DownloadRequestManager::delegate_->ShouldAllowDownload());
} else {
- dialog_delegate_ = DownloadRequestDialogDelegate::Create(tab, this);
+ infobar_ = new DownloadRequestInfoBarDelegate(tab, this);
}
}
@@ -109,13 +109,8 @@ void DownloadRequestManager::TabDownloadState::Observe(
return;
}
- if (is_showing_prompt()) {
- // We're prompting the user and they navigated away. Close the popup and
- // cancel the downloads.
- dialog_delegate_->CloseWindow();
- // After switch we'll notify callbacks and get deleted.
- } else if (status_ == DownloadRequestManager::ALLOW_ALL_DOWNLOADS ||
- status_ == DownloadRequestManager::DOWNLOADS_NOT_ALLOWED) {
+ if (status_ == DownloadRequestManager::ALLOW_ALL_DOWNLOADS ||
+ status_ == DownloadRequestManager::DOWNLOADS_NOT_ALLOWED) {
// User has either allowed all downloads or canceled all downloads. Only
// reset the download state if the user is navigating to a different
// host (or host is empty).
@@ -123,8 +118,7 @@ void DownloadRequestManager::TabDownloadState::Observe(
entry->url().host() == initial_page_host_) {
return;
}
- } // else case: we're not prompting user and user hasn't allowed or
- // disallowed downloads, break so that we get deleted after switch.
+ }
break;
}
@@ -142,10 +136,10 @@ void DownloadRequestManager::TabDownloadState::Observe(
}
void DownloadRequestManager::TabDownloadState::NotifyCallbacks(bool allow) {
- if (dialog_delegate_) {
+ if (infobar_) {
// Reset the delegate so we don't get notified again.
- dialog_delegate_->set_host(NULL);
- dialog_delegate_ = NULL;
+ infobar_->set_host(NULL);
+ infobar_ = NULL;
}
status_ = allow ?
DownloadRequestManager::ALLOW_ALL_DOWNLOADS :
diff --git a/chrome/browser/download/download_request_manager.h b/chrome/browser/download/download_request_manager.h
index f9351c8..8844de7 100644
--- a/chrome/browser/download/download_request_manager.h
+++ b/chrome/browser/download/download_request_manager.h
@@ -13,7 +13,7 @@
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
-class DownloadRequestDialogDelegate;
+class DownloadRequestInfoBarDelegate;
class MessageLoop;
class NavigationController;
class TabContents;
@@ -60,8 +60,7 @@ class DownloadRequestManager :
};
// TabDownloadState maintains the download state for a particular tab.
- // TabDownloadState installs observers to update the download status
- // appropriately. Additionally TabDownloadState prompts the user as necessary.
+ // TabDownloadState prompts the user with an infobar as necessary.
// TabDownloadState deletes itself (by invoking
// DownloadRequestManager::Remove) as necessary.
class TabDownloadState : public NotificationObserver {
@@ -96,15 +95,24 @@ class DownloadRequestManager :
DownloadRequestManager::Callback* callback);
// Are we showing a prompt to the user?
- bool is_showing_prompt() const { return (dialog_delegate_ != NULL); }
+ bool is_showing_prompt() const { return (infobar_ != NULL); }
// NavigationController we're tracking.
NavigationController* controller() const { return controller_; }
// Invoked from DownloadRequestDialogDelegate. Notifies the delegates and
- // changes the status appropriately.
- void Cancel();
- void Accept();
+ // changes the status appropriately. Virtual for testing.
+ virtual void Cancel();
+ virtual void Accept();
+
+ protected:
+ // Used for testing.
+ TabDownloadState()
+ : host_(NULL),
+ controller_(NULL),
+ status_(DownloadRequestManager::ALLOW_ONE_DOWNLOAD),
+ infobar_(NULL) {
+ }
private:
// NotificationObserver method.
@@ -134,8 +142,8 @@ class DownloadRequestManager :
// Used to remove observers installed on NavigationController.
NotificationRegistrar registrar_;
- // Handles showing the dialog to the user, may be null.
- DownloadRequestDialogDelegate* dialog_delegate_;
+ // Handles showing the infobar to the user, may be null.
+ DownloadRequestInfoBarDelegate* infobar_;
DISALLOW_COPY_AND_ASSIGN(TabDownloadState);
};