diff options
-rw-r--r-- | chrome/browser/download/download_browsertest.cc | 10 | ||||
-rw-r--r-- | chrome/browser/download/download_request_limiter.cc | 150 | ||||
-rw-r--r-- | chrome/browser/download/download_request_limiter.h | 35 | ||||
-rw-r--r-- | chrome/browser/download/download_request_limiter_observer.cc | 24 | ||||
-rw-r--r-- | chrome/browser/download/download_request_limiter_observer.h | 23 | ||||
-rw-r--r-- | chrome/browser/download/download_request_limiter_unittest.cc | 88 | ||||
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents_wrapper.cc | 3 | ||||
-rw-r--r-- | chrome/browser/ui/tab_contents/tab_contents_wrapper.h | 15 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
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', |