summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/download/download_browsertest.cc10
-rw-r--r--chrome/browser/download/download_request_limiter.cc150
-rw-r--r--chrome/browser/download/download_request_limiter.h35
-rw-r--r--chrome/browser/download/download_request_limiter_observer.cc24
-rw-r--r--chrome/browser/download/download_request_limiter_observer.h23
-rw-r--r--chrome/browser/download/download_request_limiter_unittest.cc88
-rw-r--r--chrome/browser/ui/tab_contents/tab_contents_wrapper.cc3
-rw-r--r--chrome/browser/ui/tab_contents/tab_contents_wrapper.h15
-rw-r--r--chrome/chrome_browser.gypi2
9 files changed, 195 insertions, 155 deletions
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc
index 097c951..25c86e8 100644
--- a/chrome/browser/download/download_browsertest.cc
+++ b/chrome/browser/download/download_browsertest.cc
@@ -961,13 +961,10 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadResourceThrottleCancels) {
EXPECT_TRUE(EnsureNoPendingDownloads());
// Disable downloads for the tab.
- content::NavigationController* controller =
- &browser()->GetSelectedWebContents()->GetController();
+ WebContents* web_contents = browser()->GetSelectedWebContents();
DownloadRequestLimiter::TabDownloadState* tab_download_state =
g_browser_process->download_request_limiter()->GetDownloadState(
- controller,
- controller,
- true);
+ web_contents, web_contents, true);
ASSERT_TRUE(tab_download_state);
tab_download_state->set_download_status(
DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED);
@@ -975,7 +972,8 @@ IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadResourceThrottleCancels) {
// Try to start the download via Javascript and wait for the corresponding
// load stop event.
TestNavigationObserver observer(
- content::Source<content::NavigationController>(controller),
+ content::Source<content::NavigationController>(
+ &web_contents->GetController()),
NULL,
1);
bool download_assempted;
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc
index 91bb6cb..f14782e 100644
--- a/chrome/browser/download/download_request_limiter.cc
+++ b/chrome/browser/download/download_request_limiter.cc
@@ -29,23 +29,24 @@ using content::WebContents;
DownloadRequestLimiter::TabDownloadState::TabDownloadState(
DownloadRequestLimiter* host,
- NavigationController* controller,
- NavigationController* originating_controller)
- : host_(host),
- controller_(controller),
+ WebContents* contents,
+ WebContents* originating_web_contents)
+ : content::WebContentsObserver(contents),
+ host_(host),
status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
download_count_(0),
infobar_(NULL) {
- content::Source<NavigationController> notification_source(controller);
- content::Source<content::WebContents> web_contents_source(
- controller->GetWebContents());
+ content::Source<NavigationController> notification_source(
+ &contents->GetController());
+ content::Source<content::WebContents> web_contents_source(contents);
registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
notification_source);
registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
web_contents_source);
- NavigationEntry* active_entry = originating_controller ?
- originating_controller->GetActiveEntry() : controller->GetActiveEntry();
+ NavigationEntry* active_entry = originating_web_contents ?
+ originating_web_contents->GetController().GetActiveEntry() :
+ contents->GetController().GetActiveEntry();
if (active_entry)
initial_page_host_ = active_entry->GetURL().host();
}
@@ -58,23 +59,29 @@ DownloadRequestLimiter::TabDownloadState::~TabDownloadState() {
DCHECK(!infobar_);
}
-void DownloadRequestLimiter::TabDownloadState::OnUserGesture() {
+void DownloadRequestLimiter::TabDownloadState::DidGetUserGesture() {
if (is_showing_prompt()) {
// Don't change the state if the user clicks on the page some where.
return;
}
- if (status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS &&
- status_ != DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) {
+ TabContentsWrapper* tab_wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(web_contents());
+ // See PromptUserForDownload(): if there's no TCW, then DOWNLOADS_NOT_ALLOWED
+ // is functionally equivalent to PROMPT_BEFORE_DOWNLOAD.
+ if ((tab_wrapper &&
+ status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS &&
+ status_ != DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) ||
+ (!tab_wrapper &&
+ status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS)) {
// Revert to default status.
host_->Remove(this);
// WARNING: We've been deleted.
- return;
}
}
void DownloadRequestLimiter::TabDownloadState::PromptUserForDownload(
- WebContents* tab,
+ WebContents* web_contents,
const DownloadRequestLimiter::Callback& callback) {
callbacks_.push_back(callback);
@@ -83,13 +90,25 @@ void DownloadRequestLimiter::TabDownloadState::PromptUserForDownload(
if (DownloadRequestLimiter::delegate_) {
NotifyCallbacks(DownloadRequestLimiter::delegate_->ShouldAllowDownload());
- } else {
- InfoBarTabHelper* infobar_helper =
- TabContentsWrapper::GetCurrentWrapperForContents(tab)->
- infobar_tab_helper();
- infobar_ = new DownloadRequestInfoBarDelegate(infobar_helper, this);
- infobar_helper->AddInfoBar(infobar_);
+ return;
}
+ TabContentsWrapper* tab_wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(web_contents);
+ if (!tab_wrapper) {
+ // If |web_contents| doesn't have a tab_wrapper, then it isn't what a user
+ // thinks of as a tab, it's actually a "raw" WebContents like those used
+ // for extension popups/bubbles and hosted apps etc.
+ // TODO(benjhayden): If this is an automatic download from an extension,
+ // it would be convenient for the extension author if we send a message to
+ // the extension's DevTools console (as we do for CSP) about how
+ // extensions should use chrome.downloads.download() (requires the
+ // "downloads" permission) to automatically download >1 files.
+ Cancel();
+ return;
+ }
+ InfoBarTabHelper* infobar_helper = tab_wrapper->infobar_tab_helper();
+ infobar_ = new DownloadRequestInfoBarDelegate(infobar_helper, this);
+ infobar_helper->AddInfoBar(infobar_);
}
void DownloadRequestLimiter::TabDownloadState::Cancel() {
@@ -109,14 +128,15 @@ void DownloadRequestLimiter::TabDownloadState::Observe(
NOTREACHED();
return;
}
+ content::NavigationController* controller = &web_contents()->GetController();
if (type == content::NOTIFICATION_NAV_ENTRY_PENDING &&
- content::Source<NavigationController>(source).ptr() != controller_) {
+ content::Source<NavigationController>(source).ptr() != controller) {
NOTREACHED();
return;
}
if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED &&
&content::Source<content::WebContents>(source).ptr()->
- GetController() != controller_) {
+ GetController() != controller) {
NOTREACHED();
return;
}
@@ -129,7 +149,7 @@ void DownloadRequestLimiter::TabDownloadState::Observe(
// request. If this happens we may let a download through that we
// shouldn't have. But this is rather rare, and it is difficult to get
// 100% right, so we don't deal with it.
- NavigationEntry* entry = controller_->GetPendingEntry();
+ NavigationEntry* entry = controller->GetPendingEntry();
if (!entry)
return;
@@ -165,9 +185,9 @@ void DownloadRequestLimiter::TabDownloadState::Observe(
}
void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
- status_ = allow ?
+ set_download_status(allow ?
DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS :
- DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED;
+ DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED);
std::vector<DownloadRequestLimiter::Callback> callbacks;
bool change_status = false;
@@ -195,7 +215,7 @@ void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
host_->ScheduleNotification(callbacks[i], allow);
if (change_status)
- status_ = DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD;
+ set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD);
}
// DownloadRequestLimiter ------------------------------------------------------
@@ -210,8 +230,8 @@ DownloadRequestLimiter::~DownloadRequestLimiter() {
}
DownloadRequestLimiter::DownloadStatus
- DownloadRequestLimiter::GetDownloadStatus(WebContents* tab) {
- TabDownloadState* state = GetDownloadState(&tab->GetController(), NULL, false);
+ DownloadRequestLimiter::GetDownloadStatus(WebContents* web_contents) {
+ TabDownloadState* state = GetDownloadState(web_contents, NULL, false);
return state ? state->download_status() : ALLOW_ONE_DOWNLOAD;
}
@@ -231,26 +251,18 @@ void DownloadRequestLimiter::CanDownloadOnIOThread(
request_method, callback));
}
-void DownloadRequestLimiter::OnUserGesture(WebContents* tab) {
- TabDownloadState* state =
- GetDownloadState(&tab->GetController(), NULL, false);
- if (!state)
- return;
-
- state->OnUserGesture();
-}
-
// static
void DownloadRequestLimiter::SetTestingDelegate(TestingDelegate* delegate) {
delegate_ = delegate;
}
-DownloadRequestLimiter::TabDownloadState* DownloadRequestLimiter::
- GetDownloadState(NavigationController* controller,
- NavigationController* originating_controller,
- bool create) {
- DCHECK(controller);
- StateMap::iterator i = state_map_.find(controller);
+DownloadRequestLimiter::TabDownloadState*
+DownloadRequestLimiter::GetDownloadState(
+ WebContents* web_contents,
+ WebContents* originating_web_contents,
+ bool create) {
+ DCHECK(web_contents);
+ StateMap::iterator i = state_map_.find(web_contents);
if (i != state_map_.end())
return i->second;
@@ -258,8 +270,8 @@ DownloadRequestLimiter::TabDownloadState* DownloadRequestLimiter::
return NULL;
TabDownloadState* state =
- new TabDownloadState(this, controller, originating_controller);
- state_map_[controller] = state;
+ new TabDownloadState(this, web_contents, originating_web_contents);
+ state_map_[web_contents] = state;
return state;
}
@@ -270,49 +282,53 @@ void DownloadRequestLimiter::CanDownload(int render_process_host_id,
const Callback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- WebContents* originating_tab =
+ WebContents* originating_contents =
tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
- if (!originating_tab) {
- // The tab was closed, don't allow the download.
+ if (!originating_contents) {
+ // The WebContents was closed, don't allow the download.
ScheduleNotification(callback, false);
return;
}
CanDownloadImpl(
- TabContentsWrapper::GetCurrentWrapperForContents(originating_tab),
+ originating_contents,
request_id,
request_method,
callback);
}
-void DownloadRequestLimiter::CanDownloadImpl(
- TabContentsWrapper* originating_tab,
- int request_id,
- const std::string& request_method,
- const Callback& callback) {
- DCHECK(originating_tab);
+void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents,
+ int request_id,
+ const std::string& request_method,
+ const Callback& callback) {
+ DCHECK(originating_contents);
// FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order
// to cancel the download operation in chrome and let the host browser
// take care of it.
- WebContents* tab = originating_tab->web_contents();
- if (tab->GetDelegate() && !tab->GetDelegate()->CanDownload(
- tab->GetRenderViewHost(), request_id, request_method)) {
+ if (originating_contents->GetDelegate() &&
+ !originating_contents->GetDelegate()->CanDownload(
+ originating_contents->GetRenderViewHost(),
+ request_id,
+ request_method)) {
ScheduleNotification(callback, false);
return;
}
// If the tab requesting the download is a constrained popup that is not
// shown, treat the request as if it came from the parent.
- TabContentsWrapper* effective_wrapper = originating_tab;
- if (effective_wrapper->blocked_content_tab_helper()->delegate()) {
- effective_wrapper = effective_wrapper->blocked_content_tab_helper()->
- delegate()->GetConstrainingContentsWrapper(effective_wrapper);
+ WebContents* effective_contents = originating_contents;
+ TabContentsWrapper* originating_wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(originating_contents);
+ if (originating_wrapper &&
+ originating_wrapper->blocked_content_tab_helper()->delegate()) {
+ effective_contents = originating_wrapper->blocked_content_tab_helper()->
+ delegate()->GetConstrainingContentsWrapper(originating_wrapper)->
+ web_contents();
}
TabDownloadState* state = GetDownloadState(
- &effective_wrapper->web_contents()->GetController(),
- &tab->GetController(), true);
+ effective_contents, originating_contents, true);
switch (state->download_status()) {
case ALLOW_ALL_DOWNLOADS:
if (state->download_count() && !(state->download_count() %
@@ -332,7 +348,7 @@ void DownloadRequestLimiter::CanDownloadImpl(
break;
case PROMPT_BEFORE_DOWNLOAD:
- state->PromptUserForDownload(effective_wrapper->web_contents(), callback);
+ state->PromptUserForDownload(effective_contents, callback);
state->increment_download_count();
break;
@@ -348,8 +364,8 @@ void DownloadRequestLimiter::ScheduleNotification(const Callback& callback,
}
void DownloadRequestLimiter::Remove(TabDownloadState* state) {
- DCHECK(ContainsKey(state_map_, state->controller()));
- state_map_.erase(state->controller());
+ DCHECK(ContainsKey(state_map_, state->web_contents()));
+ state_map_.erase(state->web_contents());
delete state;
}
diff --git a/chrome/browser/download/download_request_limiter.h b/chrome/browser/download/download_request_limiter.h
index 457de30..420de0e 100644
--- a/chrome/browser/download/download_request_limiter.h
+++ b/chrome/browser/download/download_request_limiter.h
@@ -15,6 +15,7 @@
#include "base/memory/ref_counted.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/web_contents_observer.h"
class DownloadRequestInfoBarDelegate;
class TabContentsWrapper;
@@ -68,7 +69,8 @@ class DownloadRequestLimiter
// TabDownloadState prompts the user with an infobar as necessary.
// TabDownloadState deletes itself (by invoking
// DownloadRequestLimiter::Remove) as necessary.
- class TabDownloadState : public content::NotificationObserver {
+ class TabDownloadState : public content::NotificationObserver,
+ public content::WebContentsObserver {
public:
// Creates a new TabDownloadState. |controller| is the controller the
// TabDownloadState tracks the state of and is the host for any dialogs that
@@ -77,8 +79,8 @@ class DownloadRequestLimiter
// is used. |originating_controller| is typically null, but differs from
// |controller| in the case of a constrained popup requesting the download.
TabDownloadState(DownloadRequestLimiter* host,
- content::NavigationController* controller,
- content::NavigationController* originating_controller);
+ content::WebContents* web_contents,
+ content::WebContents* originating_web_contents);
virtual ~TabDownloadState();
// Status of the download.
@@ -97,9 +99,15 @@ class DownloadRequestLimiter
return download_count_;
}
+ // Promote protected accessor to public.
+ content::WebContents* web_contents() {
+ return content::WebContentsObserver::web_contents();
+ }
+
+ // content::WebContentsObserver overrides.
// Invoked when a user gesture occurs (mouse click, enter or space). This
// may result in invoking Remove on DownloadRequestLimiter.
- void OnUserGesture();
+ virtual void DidGetUserGesture() OVERRIDE;
// Asks the user if they really want to allow the download.
// See description above CanDownloadOnIOThread for details on lifetime of
@@ -111,9 +119,6 @@ class DownloadRequestLimiter
// Are we showing a prompt to the user?
bool is_showing_prompt() const { return (infobar_ != NULL); }
- // NavigationController we're tracking.
- content::NavigationController* controller() const { return controller_; }
-
// Invoked from DownloadRequestDialogDelegate. Notifies the delegates and
// changes the status appropriately. Virtual for testing.
virtual void Cancel();
@@ -123,7 +128,6 @@ class DownloadRequestLimiter
// Used for testing.
TabDownloadState()
: host_(NULL),
- controller_(NULL),
status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
download_count_(0),
infobar_(NULL) {
@@ -141,8 +145,6 @@ class DownloadRequestLimiter
DownloadRequestLimiter* host_;
- content::NavigationController* controller_;
-
// Host of the first page the download started on. This may be empty.
std::string initial_page_host_;
@@ -179,11 +181,6 @@ class DownloadRequestLimiter
const std::string& request_method,
const Callback& callback);
- // Invoked when the user presses the mouse, enter key or space bar. This may
- // change the download status for the page. See the class description for
- // details.
- void OnUserGesture(content::WebContents* tab);
-
private:
FRIEND_TEST_ALL_PREFIXES(DownloadTest, DownloadResourceThrottleCancels);
friend class base::RefCountedThreadSafe<DownloadRequestLimiter>;
@@ -210,8 +207,8 @@ class DownloadRequestLimiter
// The returned TabDownloadState is owned by the DownloadRequestLimiter and
// deleted when no longer needed (the Remove method is invoked).
TabDownloadState* GetDownloadState(
- content::NavigationController* controller,
- content::NavigationController* originating_controller,
+ content::WebContents* web_contents,
+ content::WebContents* originating_web_contents,
bool create);
// CanDownloadOnIOThread invokes this on the UI thread. This determines the
@@ -224,7 +221,7 @@ class DownloadRequestLimiter
// Does the work of updating the download status on the UI thread and
// potentially prompting the user.
- void CanDownloadImpl(TabContentsWrapper* originating_tab,
+ void CanDownloadImpl(content::WebContents* originating_contents,
int request_id,
const std::string& request_method,
const Callback& callback);
@@ -242,7 +239,7 @@ class DownloadRequestLimiter
// if the state is other than ALLOW_ONE_DOWNLOAD. Similarly once the state
// transitions from anything but ALLOW_ONE_DOWNLOAD back to ALLOW_ONE_DOWNLOAD
// the TabDownloadState is removed and deleted (by way of Remove).
- typedef std::map<content::NavigationController*, TabDownloadState*> StateMap;
+ typedef std::map<content::WebContents*, TabDownloadState*> StateMap;
StateMap state_map_;
static TestingDelegate* delegate_;
diff --git a/chrome/browser/download/download_request_limiter_observer.cc b/chrome/browser/download/download_request_limiter_observer.cc
deleted file mode 100644
index c5bd6e7..0000000
--- a/chrome/browser/download/download_request_limiter_observer.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2011 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_limiter_observer.h"
-
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/download/download_request_limiter.h"
-
-using content::WebContents;
-
-DownloadRequestLimiterObserver::DownloadRequestLimiterObserver(
- WebContents* web_contents)
- : content::WebContentsObserver(web_contents) {
-}
-
-DownloadRequestLimiterObserver::~DownloadRequestLimiterObserver() {
-}
-
-void DownloadRequestLimiterObserver::DidGetUserGesture() {
- if (!g_browser_process->download_request_limiter())
- return; // NULL in unitests.
- g_browser_process->download_request_limiter()->OnUserGesture(web_contents());
-}
diff --git a/chrome/browser/download/download_request_limiter_observer.h b/chrome/browser/download/download_request_limiter_observer.h
deleted file mode 100644
index b0fa595..0000000
--- a/chrome/browser/download/download_request_limiter_observer.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011 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_LIMITER_OBSERVER_H_
-#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_OBSERVER_H_
-
-#include "content/public/browser/web_contents_observer.h"
-
-// Watches for user gesture notifications.
-class DownloadRequestLimiterObserver : public content::WebContentsObserver {
- public:
- explicit DownloadRequestLimiterObserver(content::WebContents* web_contents);
- virtual ~DownloadRequestLimiterObserver();
-
- // content::WebContentsObserver overrides.
- virtual void DidGetUserGesture() OVERRIDE;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiterObserver);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_OBSERVER_H_
diff --git a/chrome/browser/download/download_request_limiter_unittest.cc b/chrome/browser/download/download_request_limiter_unittest.cc
index 0bbbf40d..46fd609 100644
--- a/chrome/browser/download/download_request_limiter_unittest.cc
+++ b/chrome/browser/download/download_request_limiter_unittest.cc
@@ -4,13 +4,16 @@
#include "base/bind.h"
#include "chrome/browser/download/download_request_limiter.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/web_contents.h"
#include "content/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::BrowserThread;
+using content::WebContents;
class DownloadRequestLimiterTest : public TabContentsWrapperTestHarness {
public:
@@ -33,14 +36,21 @@ class DownloadRequestLimiterTest : public TabContentsWrapperTestHarness {
}
virtual void TearDown() {
- DownloadRequestLimiter::SetTestingDelegate(NULL);
-
+ UnsetDelegate();
TabContentsWrapperTestHarness::TearDown();
}
+ virtual void UnsetDelegate() {
+ DownloadRequestLimiter::SetTestingDelegate(NULL);
+ }
+
void CanDownload() {
+ CanDownloadFor(web_contents());
+ }
+
+ void CanDownloadFor(WebContents* web_contents) {
download_request_limiter_->CanDownloadImpl(
- contents_wrapper(),
+ web_contents,
-1, // request id
"GET", // request method
base::Bind(&DownloadRequestLimiterTest::ContinueDownload,
@@ -48,6 +58,17 @@ class DownloadRequestLimiterTest : public TabContentsWrapperTestHarness {
message_loop_.RunAllPending();
}
+ void OnUserGesture() {
+ OnUserGestureFor(web_contents());
+ }
+
+ void OnUserGestureFor(WebContents* web_contents) {
+ DownloadRequestLimiter::TabDownloadState* state =
+ download_request_limiter_->GetDownloadState(web_contents, NULL, false);
+ if (state)
+ state->DidGetUserGesture();
+ }
+
bool ShouldAllowDownload() {
ask_allow_count_++;
return allow_download_;
@@ -97,7 +118,8 @@ class DownloadRequestLimiterTest : public TabContentsWrapperTestHarness {
content::TestBrowserThread io_thread_;
};
-TEST_F(DownloadRequestLimiterTest, Allow) {
+TEST_F(DownloadRequestLimiterTest,
+ DownloadRequestLimiter_Allow) {
// All tabs should initially start at ALLOW_ONE_DOWNLOAD.
ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
download_request_limiter_->GetDownloadStatus(contents()));
@@ -137,7 +159,8 @@ TEST_F(DownloadRequestLimiterTest, Allow) {
continue_count_ = 0;
}
-TEST_F(DownloadRequestLimiterTest, ResetOnNavigation) {
+TEST_F(DownloadRequestLimiterTest,
+ DownloadRequestLimiter_ResetOnNavigation) {
NavigateAndCommit(GURL("http://foo.com/bar"));
// Do two downloads, allowing the second so that we end up with allow all.
@@ -161,7 +184,7 @@ TEST_F(DownloadRequestLimiterTest, ResetOnNavigation) {
// Do a user gesture, because we're at allow all, this shouldn't change the
// state.
- download_request_limiter_->OnUserGesture(contents());
+ OnUserGesture();
ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
download_request_limiter_->GetDownloadStatus(contents()));
@@ -171,7 +194,8 @@ TEST_F(DownloadRequestLimiterTest, ResetOnNavigation) {
download_request_limiter_->GetDownloadStatus(contents()));
}
-TEST_F(DownloadRequestLimiterTest, ResetOnUserGesture) {
+TEST_F(DownloadRequestLimiterTest,
+ DownloadRequestLimiter_ResetOnUserGesture) {
NavigateAndCommit(GURL("http://foo.com/bar"));
// Do one download, which should change to prompt before download.
@@ -181,7 +205,7 @@ TEST_F(DownloadRequestLimiterTest, ResetOnUserGesture) {
download_request_limiter_->GetDownloadStatus(contents()));
// Do a user gesture, which should reset back to allow one.
- download_request_limiter_->OnUserGesture(contents());
+ OnUserGesture();
ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
download_request_limiter_->GetDownloadStatus(contents()));
@@ -194,7 +218,7 @@ TEST_F(DownloadRequestLimiterTest, ResetOnUserGesture) {
download_request_limiter_->GetDownloadStatus(contents()));
// A user gesture now should NOT change the state.
- download_request_limiter_->OnUserGesture(contents());
+ OnUserGesture();
ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
download_request_limiter_->GetDownloadStatus(contents()));
// And make sure we really can't download.
@@ -207,3 +231,49 @@ TEST_F(DownloadRequestLimiterTest, ResetOnUserGesture) {
ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
download_request_limiter_->GetDownloadStatus(contents()));
}
+
+TEST_F(DownloadRequestLimiterTest,
+ DownloadRequestLimiter_RawWebContents) {
+ // By-pass TabContentsWrapperTestHarness and use
+ // RenderViewHostTestHarness::CreateTestWebContents() directly so that there
+ // will be no TabContentsWrapper for web_contents.
+ scoped_ptr<WebContents> web_contents(CreateTestWebContents());
+ TabContentsWrapper* tab_wrapper =
+ TabContentsWrapper::GetCurrentWrapperForContents(web_contents.get());
+ ASSERT_TRUE(tab_wrapper == NULL);
+ // DRL won't try to make an infobar if it doesn't have a TCW, and we want to
+ // test that it will Cancel() instead of prompting when it doesn't have a TCW,
+ // so unset the delegate.
+ UnsetDelegate();
+ EXPECT_EQ(0, continue_count_);
+ EXPECT_EQ(0, cancel_count_);
+ EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+ // You get one freebie.
+ CanDownloadFor(web_contents.get());
+ EXPECT_EQ(1, continue_count_);
+ EXPECT_EQ(0, cancel_count_);
+ EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+ OnUserGestureFor(web_contents.get());
+ EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+ CanDownloadFor(web_contents.get());
+ EXPECT_EQ(2, continue_count_);
+ EXPECT_EQ(0, cancel_count_);
+ EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+ CanDownloadFor(web_contents.get());
+ EXPECT_EQ(2, continue_count_);
+ EXPECT_EQ(1, cancel_count_);
+ EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+ OnUserGestureFor(web_contents.get());
+ EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+ CanDownloadFor(web_contents.get());
+ EXPECT_EQ(3, continue_count_);
+ EXPECT_EQ(1, cancel_count_);
+ EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
+ download_request_limiter_->GetDownloadStatus(web_contents.get()));
+}
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
index 08eea8d..b9c464e 100644
--- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
+++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
@@ -11,7 +11,6 @@
#include "chrome/browser/autofill/autofill_manager.h"
#include "chrome/browser/automation/automation_tab_helper.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
-#include "chrome/browser/download/download_request_limiter_observer.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
#include "chrome/browser/extensions/extension_tab_helper.h"
#include "chrome/browser/external_protocol/external_protocol_observer.h"
@@ -126,8 +125,6 @@ TabContentsWrapper::TabContentsWrapper(WebContents* contents)
// Create the per-tab observers.
alternate_error_page_tab_observer_.reset(
new AlternateErrorPageTabObserver(contents, profile()));
- download_request_limiter_observer_.reset(
- new DownloadRequestLimiterObserver(contents));
webnavigation_observer_.reset(
new extensions::WebNavigationTabObserver(contents));
external_protocol_observer_.reset(new ExternalProtocolObserver(contents));
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h
index 83a5d3f..3bff9f2 100644
--- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h
+++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h
@@ -22,7 +22,6 @@ class BlockedContentTabHelper;
class BookmarkTabHelper;
class ConstrainedWindowTabHelper;
class CoreTabHelper;
-class DownloadRequestLimiterObserver;
class ExtensionTabHelper;
class ExternalProtocolObserver;
class FaviconTabHelper;
@@ -75,6 +74,19 @@ class SafeBrowsingTabObserver;
// Wraps WebContents and all of its supporting objects in order to control
// their ownership and lifetime.
//
+// WARNING: Not every place where HTML can run has a TabContentsWrapper. This
+// class is *only* used in a visible, actual, tab inside a browser. Examples of
+// things that do not have tab wrappers include:
+// - Extension background pages and popup bubbles
+// - HTML notification bubbles
+// - Screensavers on Chrome OS
+// - Other random places we decide to display HTML over time
+//
+// Consider carefully whether your feature is something that makes sense only
+// when a tab is displayed, or could make sense in other cases we use HTML. It
+// may makes sense to push down into WebContents and make configurable, or at
+// least to make easy for other WebContents hosts to include and support.
+//
// TODO(avi): Eventually, this class will become TabContents as far as
// the browser front-end is concerned.
class TabContentsWrapper : public content::WebContentsObserver {
@@ -271,7 +283,6 @@ class TabContentsWrapper : public content::WebContentsObserver {
// and silently do their thing live here.)
scoped_ptr<AlternateErrorPageTabObserver> alternate_error_page_tab_observer_;
- scoped_ptr<DownloadRequestLimiterObserver> download_request_limiter_observer_;
scoped_ptr<extensions::WebNavigationTabObserver> webnavigation_observer_;
scoped_ptr<ExternalProtocolObserver> external_protocol_observer_;
scoped_ptr<OmniboxSearchHint> omnibox_search_hint_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index cc9f0b7..e42cea9 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -966,8 +966,6 @@
'browser/download/download_request_infobar_delegate.h',
'browser/download/download_request_limiter.cc',
'browser/download/download_request_limiter.h',
- 'browser/download/download_request_limiter_observer.cc',
- 'browser/download/download_request_limiter_observer.h',
'browser/download/download_service.cc',
'browser/download/download_service.h',
'browser/download/download_service_factory.cc',