diff options
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_ |