| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_ | 5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_ |
| 6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_ | 6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
| 15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
| 16 #include "content/public/browser/notification_observer.h" | 16 #include "content/public/browser/notification_observer.h" |
| 17 #include "content/public/browser/notification_registrar.h" | 17 #include "content/public/browser/notification_registrar.h" |
| 18 #include "content/public/browser/web_contents_observer.h" |
| 18 | 19 |
| 19 class DownloadRequestInfoBarDelegate; | 20 class DownloadRequestInfoBarDelegate; |
| 20 class TabContentsWrapper; | 21 class TabContentsWrapper; |
| 21 | 22 |
| 22 namespace content { | 23 namespace content { |
| 23 class NavigationController; | 24 class NavigationController; |
| 24 class WebContents; | 25 class WebContents; |
| 25 } | 26 } |
| 26 | 27 |
| 27 // DownloadRequestLimiter is responsible for determining whether a download | 28 // DownloadRequestLimiter is responsible for determining whether a download |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 static const size_t kMaxDownloadsAtOnce = 50; | 62 static const size_t kMaxDownloadsAtOnce = 50; |
| 62 | 63 |
| 63 // The callback from CanDownloadOnIOThread. This is invoked on the io thread. | 64 // The callback from CanDownloadOnIOThread. This is invoked on the io thread. |
| 64 // The boolean parameter indicates whether or not the download is allowed. | 65 // The boolean parameter indicates whether or not the download is allowed. |
| 65 typedef base::Callback<void(bool /*allow*/)> Callback; | 66 typedef base::Callback<void(bool /*allow*/)> Callback; |
| 66 | 67 |
| 67 // TabDownloadState maintains the download state for a particular tab. | 68 // TabDownloadState maintains the download state for a particular tab. |
| 68 // TabDownloadState prompts the user with an infobar as necessary. | 69 // TabDownloadState prompts the user with an infobar as necessary. |
| 69 // TabDownloadState deletes itself (by invoking | 70 // TabDownloadState deletes itself (by invoking |
| 70 // DownloadRequestLimiter::Remove) as necessary. | 71 // DownloadRequestLimiter::Remove) as necessary. |
| 71 class TabDownloadState : public content::NotificationObserver { | 72 class TabDownloadState : public content::NotificationObserver, |
| 73 public content::WebContentsObserver { |
| 72 public: | 74 public: |
| 73 // Creates a new TabDownloadState. |controller| is the controller the | 75 // Creates a new TabDownloadState. |controller| is the controller the |
| 74 // TabDownloadState tracks the state of and is the host for any dialogs that | 76 // TabDownloadState tracks the state of and is the host for any dialogs that |
| 75 // are displayed. |originating_controller| is used to determine the host of | 77 // are displayed. |originating_controller| is used to determine the host of |
| 76 // the initial download. If |originating_controller| is null, |controller| | 78 // the initial download. If |originating_controller| is null, |controller| |
| 77 // is used. |originating_controller| is typically null, but differs from | 79 // is used. |originating_controller| is typically null, but differs from |
| 78 // |controller| in the case of a constrained popup requesting the download. | 80 // |controller| in the case of a constrained popup requesting the download. |
| 79 TabDownloadState(DownloadRequestLimiter* host, | 81 TabDownloadState(DownloadRequestLimiter* host, |
| 80 content::NavigationController* controller, | 82 content::WebContents* web_contents, |
| 81 content::NavigationController* originating_controller); | 83 content::WebContents* originating_web_contents); |
| 82 virtual ~TabDownloadState(); | 84 virtual ~TabDownloadState(); |
| 83 | 85 |
| 84 // Status of the download. | 86 // Status of the download. |
| 85 void set_download_status(DownloadRequestLimiter::DownloadStatus status) { | 87 void set_download_status(DownloadRequestLimiter::DownloadStatus status) { |
| 86 status_ = status; | 88 status_ = status; |
| 87 } | 89 } |
| 88 DownloadRequestLimiter::DownloadStatus download_status() const { | 90 DownloadRequestLimiter::DownloadStatus download_status() const { |
| 89 return status_; | 91 return status_; |
| 90 } | 92 } |
| 91 | 93 |
| 92 // Number of "ALLOWED" downloads. | 94 // Number of "ALLOWED" downloads. |
| 93 void increment_download_count() { | 95 void increment_download_count() { |
| 94 download_count_++; | 96 download_count_++; |
| 95 } | 97 } |
| 96 size_t download_count() const { | 98 size_t download_count() const { |
| 97 return download_count_; | 99 return download_count_; |
| 98 } | 100 } |
| 99 | 101 |
| 102 // Promote protected accessor to public. |
| 103 content::WebContents* web_contents() { |
| 104 return content::WebContentsObserver::web_contents(); |
| 105 } |
| 106 |
| 107 // content::WebContentsObserver overrides. |
| 100 // Invoked when a user gesture occurs (mouse click, enter or space). This | 108 // Invoked when a user gesture occurs (mouse click, enter or space). This |
| 101 // may result in invoking Remove on DownloadRequestLimiter. | 109 // may result in invoking Remove on DownloadRequestLimiter. |
| 102 void OnUserGesture(); | 110 virtual void DidGetUserGesture() OVERRIDE; |
| 103 | 111 |
| 104 // Asks the user if they really want to allow the download. | 112 // Asks the user if they really want to allow the download. |
| 105 // See description above CanDownloadOnIOThread for details on lifetime of | 113 // See description above CanDownloadOnIOThread for details on lifetime of |
| 106 // callback. | 114 // callback. |
| 107 void PromptUserForDownload( | 115 void PromptUserForDownload( |
| 108 content::WebContents* tab, | 116 content::WebContents* tab, |
| 109 const DownloadRequestLimiter::Callback& callback); | 117 const DownloadRequestLimiter::Callback& callback); |
| 110 | 118 |
| 111 // Are we showing a prompt to the user? | 119 // Are we showing a prompt to the user? |
| 112 bool is_showing_prompt() const { return (infobar_ != NULL); } | 120 bool is_showing_prompt() const { return (infobar_ != NULL); } |
| 113 | 121 |
| 114 // NavigationController we're tracking. | |
| 115 content::NavigationController* controller() const { return controller_; } | |
| 116 | |
| 117 // Invoked from DownloadRequestDialogDelegate. Notifies the delegates and | 122 // Invoked from DownloadRequestDialogDelegate. Notifies the delegates and |
| 118 // changes the status appropriately. Virtual for testing. | 123 // changes the status appropriately. Virtual for testing. |
| 119 virtual void Cancel(); | 124 virtual void Cancel(); |
| 120 virtual void Accept(); | 125 virtual void Accept(); |
| 121 | 126 |
| 122 protected: | 127 protected: |
| 123 // Used for testing. | 128 // Used for testing. |
| 124 TabDownloadState() | 129 TabDownloadState() |
| 125 : host_(NULL), | 130 : host_(NULL), |
| 126 controller_(NULL), | |
| 127 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), | 131 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), |
| 128 download_count_(0), | 132 download_count_(0), |
| 129 infobar_(NULL) { | 133 infobar_(NULL) { |
| 130 } | 134 } |
| 131 | 135 |
| 132 private: | 136 private: |
| 133 // content::NotificationObserver method. | 137 // content::NotificationObserver method. |
| 134 virtual void Observe(int type, | 138 virtual void Observe(int type, |
| 135 const content::NotificationSource& source, | 139 const content::NotificationSource& source, |
| 136 const content::NotificationDetails& details) OVERRIDE; | 140 const content::NotificationDetails& details) OVERRIDE; |
| 137 | 141 |
| 138 // Notifies the callbacks as to whether the download is allowed or not. | 142 // Notifies the callbacks as to whether the download is allowed or not. |
| 139 // Updates status_ appropriately. | 143 // Updates status_ appropriately. |
| 140 void NotifyCallbacks(bool allow); | 144 void NotifyCallbacks(bool allow); |
| 141 | 145 |
| 142 DownloadRequestLimiter* host_; | 146 DownloadRequestLimiter* host_; |
| 143 | 147 |
| 144 content::NavigationController* controller_; | |
| 145 | |
| 146 // Host of the first page the download started on. This may be empty. | 148 // Host of the first page the download started on. This may be empty. |
| 147 std::string initial_page_host_; | 149 std::string initial_page_host_; |
| 148 | 150 |
| 149 DownloadRequestLimiter::DownloadStatus status_; | 151 DownloadRequestLimiter::DownloadStatus status_; |
| 150 | 152 |
| 151 size_t download_count_; | 153 size_t download_count_; |
| 152 | 154 |
| 153 // Callbacks we need to notify. This is only non-empty if we're showing a | 155 // Callbacks we need to notify. This is only non-empty if we're showing a |
| 154 // dialog. | 156 // dialog. |
| 155 // See description above CanDownloadOnIOThread for details on lifetime of | 157 // See description above CanDownloadOnIOThread for details on lifetime of |
| (...skipping 16 matching lines...) Expand all Loading... |
| 172 DownloadStatus GetDownloadStatus(content::WebContents* tab); | 174 DownloadStatus GetDownloadStatus(content::WebContents* tab); |
| 173 | 175 |
| 174 // Updates the state of the page as necessary and notifies the callback. | 176 // Updates the state of the page as necessary and notifies the callback. |
| 175 // WARNING: both this call and the callback are invoked on the io thread. | 177 // WARNING: both this call and the callback are invoked on the io thread. |
| 176 void CanDownloadOnIOThread(int render_process_host_id, | 178 void CanDownloadOnIOThread(int render_process_host_id, |
| 177 int render_view_id, | 179 int render_view_id, |
| 178 int request_id, | 180 int request_id, |
| 179 const std::string& request_method, | 181 const std::string& request_method, |
| 180 const Callback& callback); | 182 const Callback& callback); |
| 181 | 183 |
| 182 // Invoked when the user presses the mouse, enter key or space bar. This may | |
| 183 // change the download status for the page. See the class description for | |
| 184 // details. | |
| 185 void OnUserGesture(content::WebContents* tab); | |
| 186 | |
| 187 private: | 184 private: |
| 188 FRIEND_TEST_ALL_PREFIXES(DownloadTest, DownloadResourceThrottleCancels); | 185 FRIEND_TEST_ALL_PREFIXES(DownloadTest, DownloadResourceThrottleCancels); |
| 189 friend class base::RefCountedThreadSafe<DownloadRequestLimiter>; | 186 friend class base::RefCountedThreadSafe<DownloadRequestLimiter>; |
| 190 friend class DownloadRequestLimiterTest; | 187 friend class DownloadRequestLimiterTest; |
| 191 friend class TabDownloadState; | 188 friend class TabDownloadState; |
| 192 | 189 |
| 193 ~DownloadRequestLimiter(); | 190 ~DownloadRequestLimiter(); |
| 194 | 191 |
| 195 // For unit tests. If non-null this is used instead of creating a dialog. | 192 // For unit tests. If non-null this is used instead of creating a dialog. |
| 196 class TestingDelegate { | 193 class TestingDelegate { |
| 197 public: | 194 public: |
| 198 virtual bool ShouldAllowDownload() = 0; | 195 virtual bool ShouldAllowDownload() = 0; |
| 199 | 196 |
| 200 protected: | 197 protected: |
| 201 virtual ~TestingDelegate() {} | 198 virtual ~TestingDelegate() {} |
| 202 }; | 199 }; |
| 203 static void SetTestingDelegate(TestingDelegate* delegate); | 200 static void SetTestingDelegate(TestingDelegate* delegate); |
| 204 | 201 |
| 205 // Gets the download state for the specified controller. If the | 202 // Gets the download state for the specified controller. If the |
| 206 // TabDownloadState does not exist and |create| is true, one is created. | 203 // TabDownloadState does not exist and |create| is true, one is created. |
| 207 // See TabDownloadState's constructor description for details on the two | 204 // See TabDownloadState's constructor description for details on the two |
| 208 // controllers. | 205 // controllers. |
| 209 // | 206 // |
| 210 // The returned TabDownloadState is owned by the DownloadRequestLimiter and | 207 // The returned TabDownloadState is owned by the DownloadRequestLimiter and |
| 211 // deleted when no longer needed (the Remove method is invoked). | 208 // deleted when no longer needed (the Remove method is invoked). |
| 212 TabDownloadState* GetDownloadState( | 209 TabDownloadState* GetDownloadState( |
| 213 content::NavigationController* controller, | 210 content::WebContents* web_contents, |
| 214 content::NavigationController* originating_controller, | 211 content::WebContents* originating_web_contents, |
| 215 bool create); | 212 bool create); |
| 216 | 213 |
| 217 // CanDownloadOnIOThread invokes this on the UI thread. This determines the | 214 // CanDownloadOnIOThread invokes this on the UI thread. This determines the |
| 218 // tab and invokes CanDownloadImpl. | 215 // tab and invokes CanDownloadImpl. |
| 219 void CanDownload(int render_process_host_id, | 216 void CanDownload(int render_process_host_id, |
| 220 int render_view_id, | 217 int render_view_id, |
| 221 int request_id, | 218 int request_id, |
| 222 const std::string& request_method, | 219 const std::string& request_method, |
| 223 const Callback& callback); | 220 const Callback& callback); |
| 224 | 221 |
| 225 // Does the work of updating the download status on the UI thread and | 222 // Does the work of updating the download status on the UI thread and |
| 226 // potentially prompting the user. | 223 // potentially prompting the user. |
| 227 void CanDownloadImpl(TabContentsWrapper* originating_tab, | 224 void CanDownloadImpl(content::WebContents* originating_contents, |
| 228 int request_id, | 225 int request_id, |
| 229 const std::string& request_method, | 226 const std::string& request_method, |
| 230 const Callback& callback); | 227 const Callback& callback); |
| 231 | 228 |
| 232 // Invoked on the UI thread. Schedules a call to NotifyCallback on the io | 229 // Invoked on the UI thread. Schedules a call to NotifyCallback on the io |
| 233 // thread. | 230 // thread. |
| 234 void ScheduleNotification(const Callback& callback, bool allow); | 231 void ScheduleNotification(const Callback& callback, bool allow); |
| 235 | 232 |
| 236 // Removes the specified TabDownloadState from the internal map and deletes | 233 // Removes the specified TabDownloadState from the internal map and deletes |
| 237 // it. This has the effect of resetting the status for the tab to | 234 // it. This has the effect of resetting the status for the tab to |
| 238 // ALLOW_ONE_DOWNLOAD. | 235 // ALLOW_ONE_DOWNLOAD. |
| 239 void Remove(TabDownloadState* state); | 236 void Remove(TabDownloadState* state); |
| 240 | 237 |
| 241 // Maps from tab to download state. The download state for a tab only exists | 238 // Maps from tab to download state. The download state for a tab only exists |
| 242 // if the state is other than ALLOW_ONE_DOWNLOAD. Similarly once the state | 239 // if the state is other than ALLOW_ONE_DOWNLOAD. Similarly once the state |
| 243 // transitions from anything but ALLOW_ONE_DOWNLOAD back to ALLOW_ONE_DOWNLOAD | 240 // transitions from anything but ALLOW_ONE_DOWNLOAD back to ALLOW_ONE_DOWNLOAD |
| 244 // the TabDownloadState is removed and deleted (by way of Remove). | 241 // the TabDownloadState is removed and deleted (by way of Remove). |
| 245 typedef std::map<content::NavigationController*, TabDownloadState*> StateMap; | 242 typedef std::map<content::WebContents*, TabDownloadState*> StateMap; |
| 246 StateMap state_map_; | 243 StateMap state_map_; |
| 247 | 244 |
| 248 static TestingDelegate* delegate_; | 245 static TestingDelegate* delegate_; |
| 249 | 246 |
| 250 DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiter); | 247 DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiter); |
| 251 }; | 248 }; |
| 252 | 249 |
| 253 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_ | 250 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_REQUEST_LIMITER_H_ |
| OLD | NEW |