diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-17 18:07:02 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-17 18:07:02 +0000 |
commit | 4cdac10757c9a774c3defdaf705f0d8c99290d19 (patch) | |
tree | d175d1d492401a5b96f3880df45c603fe05aee8a /chrome/browser/download/download_request_manager.h | |
parent | 09da32d543461c90fcf3490966e0c4a670b9a2a8 (diff) | |
download | chromium_src-4cdac10757c9a774c3defdaf705f0d8c99290d19.zip chromium_src-4cdac10757c9a774c3defdaf705f0d8c99290d19.tar.gz chromium_src-4cdac10757c9a774c3defdaf705f0d8c99290d19.tar.bz2 |
Adds the anti-carpet bombing dialog. More specifically a new
EventHandler now exists between the buffered event handler and
download event handler. This new event handler asks the
DownloadRequestManager whether the download is allowed. This may
prompt the user and then the download continues or is canceled. The
DownloadRequestManager receives the request on the IO thread, forwards
to the UI thread, makes the decision, then notifies back on the IO
thread.
BUG=3422
TEST=make sure you don't see any problems downloading content.
Review URL: http://codereview.chromium.org/7479
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3543 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/download/download_request_manager.h')
-rw-r--r-- | chrome/browser/download/download_request_manager.h | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/chrome/browser/download/download_request_manager.h b/chrome/browser/download/download_request_manager.h new file mode 100644 index 0000000..90180f8 --- /dev/null +++ b/chrome/browser/download/download_request_manager.h @@ -0,0 +1,144 @@ +// Copyright (c) 2006-2008 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_MANAGER_H_ +#define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_MANAGER_H_ + +#include <map> +#include <vector> + +#include "base/ref_counted.h" + +class MessageLoop; +class NavigationController; +class TabContents; + +// DownloadRequestManager is responsible for determining whether a download +// should be allowed or not. It is designed to keep pages from downloading +// multiple files without user interaction. DownloadRequestManager is invoked +// from ResourceDispatcherHost any time a download begins +// (CanDownloadOnIOThread). The request is processed on the UI thread, and the +// request is notified (back on the IO thread) as to whether the download should +// be allowed or denied. +// +// Invoking CanDownloadOnIOThread notifies the callback and may update the +// download status. The following details the various states: +// . Each NavigationController initially starts out allowing a download +// (ALLOW_ONE_DOWNLOAD). +// . The first time CanDownloadOnIOThread is invoked the download is allowed and +// the state changes to PROMPT_BEFORE_DOWNLOAD. +// . If the state is PROMPT_BEFORE_DOWNLOAD and the user clicks the mouse, +// presses enter, the space bar or navigates to another page the state is +// reset to ALLOW_ONE_DOWNLOAD. +// . If a download is attempted and the state is PROMPT_BEFORE_DOWNLOAD the user +// is prompted as to whether the download is allowed or disallowed. The users +// choice stays until the user navigates to a different host. For example, if +// the user allowed the download, multiple downloads are allowed without any +// user intervention until the user navigates to a different host. + +class DownloadRequestManager : + public base::RefCountedThreadSafe<DownloadRequestManager> { + public: + class TabDownloadState; + + // Download status for a particular page. See class description for details. + enum DownloadStatus { + ALLOW_ONE_DOWNLOAD, + PROMPT_BEFORE_DOWNLOAD, + ALLOW_ALL_DOWNLOADS, + DOWNLOADS_NOT_ALLOWED + }; + + DownloadRequestManager(MessageLoop* io_loop, MessageLoop* ui_loop); + ~DownloadRequestManager(); + + // The callback from CanDownloadOnIOThread. This is invoked on the io thread. + class Callback { + public: + virtual void ContinueDownload() = 0; + virtual void CancelDownload() = 0; + }; + + // Returns the download status for a page. This does not change the state in + // anyway. + DownloadStatus GetDownloadStatus(TabContents* tab); + + // Updates the state of the page as necessary and notifies the callback. + // WARNING: both this call and the callback are invoked on the io thread. + // + // DownloadRequestManager does not retain/release the Callback. It is up to + // the caller to ensure the callback is valid until the request is complete. + void CanDownloadOnIOThread(int render_process_host_id, + int render_view_id, + 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(TabContents* tab); + + private: + friend class DownloadRequestManagerTest; + friend class TabDownloadState; + + // For unit tests. If non-null this is used instead of creating a dialog. + class TestingDelegate { + public: + virtual bool ShouldAllowDownload() = 0; + }; + static void SetTestingDelegate(TestingDelegate* delegate); + + // Gets the download state for the specified controller. If the + // TabDownloadState does not exist and |create| is true, one is created. + // See TabDownloadState's constructor description for details on the two + // controllers. + // + // The returned TabDownloadState is owned by the DownloadRequestManager and + // deleted when no longer needed (the Remove method is invoked). + TabDownloadState* GetDownloadState( + NavigationController* controller, + NavigationController* originating_controller, + bool create); + + // CanDownloadOnIOThread invokes this on the UI thread. This determines the + // tab and invokes CanDownloadImpl. + void CanDownload(int render_process_host_id, + int render_view_id, + Callback* callback); + + // Does the work of updating the download status on the UI thread and + // potentially prompting the user. + void CanDownloadImpl(TabContents* originating_tab, + Callback* callback); + + // Invoked on the UI thread. Schedules a call to NotifyCallback on the io + // thread. + void ScheduleNotification(Callback* callback, bool allow); + + // Notifies the callback. This *must* be invoked on the IO thread. + void NotifyCallback(Callback* callback, bool allow); + + // Removes the specified TabDownloadState from the internal map and deletes + // it. This has the effect of resetting the status for the tab to + // ALLOW_ONE_DOWNLOAD. + void Remove(TabDownloadState* state); + + // Two threads we use. NULL during testing, in which case messages are + // dispatched immediately. + MessageLoop* io_loop_; + MessageLoop* ui_loop_; + + // Maps from tab to download state. The download state for a tab only exists + // 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<NavigationController*, TabDownloadState*> StateMap; + StateMap state_map_; + + static TestingDelegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(DownloadRequestManager); +}; + +#endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_MANAGER_H_ |