Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: chrome/browser/download/download_request_limiter.cc

Issue 10412061: Fix crashes in DownloadRequestLimiter when extension popups/bubbles initiate downloads automatically (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/download/download_request_limiter.h" 5 #include "chrome/browser/download/download_request_limiter.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "chrome/browser/download/download_request_infobar_delegate.h" 9 #include "chrome/browser/download/download_request_infobar_delegate.h"
10 #include "chrome/browser/infobars/infobar_tab_helper.h" 10 #include "chrome/browser/infobars/infobar_tab_helper.h"
(...skipping 11 matching lines...) Expand all
22 22
23 using content::BrowserThread; 23 using content::BrowserThread;
24 using content::NavigationController; 24 using content::NavigationController;
25 using content::NavigationEntry; 25 using content::NavigationEntry;
26 using content::WebContents; 26 using content::WebContents;
27 27
28 // TabDownloadState ------------------------------------------------------------ 28 // TabDownloadState ------------------------------------------------------------
29 29
30 DownloadRequestLimiter::TabDownloadState::TabDownloadState( 30 DownloadRequestLimiter::TabDownloadState::TabDownloadState(
31 DownloadRequestLimiter* host, 31 DownloadRequestLimiter* host,
32 NavigationController* controller, 32 WebContents* contents,
33 NavigationController* originating_controller) 33 WebContents* originating_web_contents)
34 : host_(host), 34 : content::WebContentsObserver(contents),
35 controller_(controller), 35 host_(host),
36 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD), 36 status_(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD),
37 download_count_(0), 37 download_count_(0),
38 infobar_(NULL) { 38 infobar_(NULL) {
39 content::Source<NavigationController> notification_source(controller); 39 content::Source<NavigationController> notification_source(
40 content::Source<content::WebContents> web_contents_source( 40 &contents->GetController());
41 controller->GetWebContents()); 41 content::Source<content::WebContents> web_contents_source(contents);
42 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, 42 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
43 notification_source); 43 notification_source);
44 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 44 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
45 web_contents_source); 45 web_contents_source);
46 46
47 NavigationEntry* active_entry = originating_controller ? 47 NavigationEntry* active_entry = originating_web_contents ?
48 originating_controller->GetActiveEntry() : controller->GetActiveEntry(); 48 originating_web_contents->GetController().GetActiveEntry() :
49 contents->GetController().GetActiveEntry();
49 if (active_entry) 50 if (active_entry)
50 initial_page_host_ = active_entry->GetURL().host(); 51 initial_page_host_ = active_entry->GetURL().host();
51 } 52 }
52 53
53 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() { 54 DownloadRequestLimiter::TabDownloadState::~TabDownloadState() {
54 // We should only be destroyed after the callbacks have been notified. 55 // We should only be destroyed after the callbacks have been notified.
55 DCHECK(callbacks_.empty()); 56 DCHECK(callbacks_.empty());
56 57
57 // And we should have closed the infobar. 58 // And we should have closed the infobar.
58 DCHECK(!infobar_); 59 DCHECK(!infobar_);
59 } 60 }
60 61
61 void DownloadRequestLimiter::TabDownloadState::OnUserGesture() { 62 void DownloadRequestLimiter::TabDownloadState::DidGetUserGesture() {
62 if (is_showing_prompt()) { 63 if (is_showing_prompt()) {
63 // Don't change the state if the user clicks on the page some where. 64 // Don't change the state if the user clicks on the page some where.
64 return; 65 return;
65 } 66 }
66 67
67 if (status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS && 68 TabContentsWrapper* tab_wrapper =
68 status_ != DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) { 69 TabContentsWrapper::GetCurrentWrapperForContents(web_contents());
70 // See PromptUserForDownload(): if there's no TCW, then DOWNLOADS_NOT_ALLOWED
71 // is functionally equivalent to PROMPT_BEFORE_DOWNLOAD.
72 if ((tab_wrapper &&
73 status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS &&
74 status_ != DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) ||
75 (!tab_wrapper &&
76 status_ != DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS)) {
69 // Revert to default status. 77 // Revert to default status.
70 host_->Remove(this); 78 host_->Remove(this);
71 // WARNING: We've been deleted. 79 // WARNING: We've been deleted.
72 return;
73 } 80 }
74 } 81 }
75 82
76 void DownloadRequestLimiter::TabDownloadState::PromptUserForDownload( 83 void DownloadRequestLimiter::TabDownloadState::PromptUserForDownload(
77 WebContents* tab, 84 WebContents* web_contents,
78 const DownloadRequestLimiter::Callback& callback) { 85 const DownloadRequestLimiter::Callback& callback) {
79 callbacks_.push_back(callback); 86 callbacks_.push_back(callback);
80 87
81 if (is_showing_prompt()) 88 if (is_showing_prompt())
82 return; // Already showing prompt. 89 return; // Already showing prompt.
83 90
84 if (DownloadRequestLimiter::delegate_) { 91 if (DownloadRequestLimiter::delegate_) {
85 NotifyCallbacks(DownloadRequestLimiter::delegate_->ShouldAllowDownload()); 92 NotifyCallbacks(DownloadRequestLimiter::delegate_->ShouldAllowDownload());
86 } else { 93 return;
87 InfoBarTabHelper* infobar_helper =
88 TabContentsWrapper::GetCurrentWrapperForContents(tab)->
89 infobar_tab_helper();
90 infobar_ = new DownloadRequestInfoBarDelegate(infobar_helper, this);
91 infobar_helper->AddInfoBar(infobar_);
92 } 94 }
95 TabContentsWrapper* tab_wrapper =
96 TabContentsWrapper::GetCurrentWrapperForContents(web_contents);
97 if (!tab_wrapper) {
98 // If |web_contents| doesn't have a tab_wrapper, then it isn't what a user
99 // thinks of as a tab, it's actually a "raw" WebContents like those used
100 // for extension popups/bubbles and hosted apps etc.
101 // TODO(benjhayden): If this is an automatic download from an extension,
102 // it would be convenient for the extension author if we send a message to
103 // the extension's DevTools console (as we do for CSP) about how
104 // extensions should use chrome.downloads.download() (requires the
105 // "downloads" permission) to automatically download >1 files.
106 Cancel();
107 return;
108 }
109 InfoBarTabHelper* infobar_helper = tab_wrapper->infobar_tab_helper();
110 infobar_ = new DownloadRequestInfoBarDelegate(infobar_helper, this);
111 infobar_helper->AddInfoBar(infobar_);
93 } 112 }
94 113
95 void DownloadRequestLimiter::TabDownloadState::Cancel() { 114 void DownloadRequestLimiter::TabDownloadState::Cancel() {
96 NotifyCallbacks(false); 115 NotifyCallbacks(false);
97 } 116 }
98 117
99 void DownloadRequestLimiter::TabDownloadState::Accept() { 118 void DownloadRequestLimiter::TabDownloadState::Accept() {
100 NotifyCallbacks(true); 119 NotifyCallbacks(true);
101 } 120 }
102 121
103 void DownloadRequestLimiter::TabDownloadState::Observe( 122 void DownloadRequestLimiter::TabDownloadState::Observe(
104 int type, 123 int type,
105 const content::NotificationSource& source, 124 const content::NotificationSource& source,
106 const content::NotificationDetails& details) { 125 const content::NotificationDetails& details) {
107 if (type != content::NOTIFICATION_NAV_ENTRY_PENDING && 126 if (type != content::NOTIFICATION_NAV_ENTRY_PENDING &&
108 type != content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { 127 type != content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
109 NOTREACHED(); 128 NOTREACHED();
110 return; 129 return;
111 } 130 }
131 content::NavigationController* controller = &web_contents()->GetController();
112 if (type == content::NOTIFICATION_NAV_ENTRY_PENDING && 132 if (type == content::NOTIFICATION_NAV_ENTRY_PENDING &&
113 content::Source<NavigationController>(source).ptr() != controller_) { 133 content::Source<NavigationController>(source).ptr() != controller) {
114 NOTREACHED(); 134 NOTREACHED();
115 return; 135 return;
116 } 136 }
117 if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED && 137 if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED &&
118 &content::Source<content::WebContents>(source).ptr()-> 138 &content::Source<content::WebContents>(source).ptr()->
119 GetController() != controller_) { 139 GetController() != controller) {
120 NOTREACHED(); 140 NOTREACHED();
121 return; 141 return;
122 } 142 }
123 143
124 switch (type) { 144 switch (type) {
125 case content::NOTIFICATION_NAV_ENTRY_PENDING: { 145 case content::NOTIFICATION_NAV_ENTRY_PENDING: {
126 // NOTE: resetting state on a pending navigate isn't ideal. In particular 146 // NOTE: resetting state on a pending navigate isn't ideal. In particular
127 // it is possible that queued up downloads for the page before the 147 // it is possible that queued up downloads for the page before the
128 // pending navigate will be delivered to us after we process this 148 // pending navigate will be delivered to us after we process this
129 // request. If this happens we may let a download through that we 149 // request. If this happens we may let a download through that we
130 // shouldn't have. But this is rather rare, and it is difficult to get 150 // shouldn't have. But this is rather rare, and it is difficult to get
131 // 100% right, so we don't deal with it. 151 // 100% right, so we don't deal with it.
132 NavigationEntry* entry = controller_->GetPendingEntry(); 152 NavigationEntry* entry = controller->GetPendingEntry();
133 if (!entry) 153 if (!entry)
134 return; 154 return;
135 155
136 if (content::PageTransitionIsRedirect(entry->GetTransitionType())) { 156 if (content::PageTransitionIsRedirect(entry->GetTransitionType())) {
137 // Redirects don't count. 157 // Redirects don't count.
138 return; 158 return;
139 } 159 }
140 160
141 if (status_ == DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS || 161 if (status_ == DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS ||
142 status_ == DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) { 162 status_ == DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED) {
(...skipping 15 matching lines...) Expand all
158 178
159 default: 179 default:
160 NOTREACHED(); 180 NOTREACHED();
161 } 181 }
162 182
163 NotifyCallbacks(false); 183 NotifyCallbacks(false);
164 host_->Remove(this); 184 host_->Remove(this);
165 } 185 }
166 186
167 void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) { 187 void DownloadRequestLimiter::TabDownloadState::NotifyCallbacks(bool allow) {
168 status_ = allow ? 188 set_download_status(allow ?
169 DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS : 189 DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS :
170 DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED; 190 DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED);
171 std::vector<DownloadRequestLimiter::Callback> callbacks; 191 std::vector<DownloadRequestLimiter::Callback> callbacks;
172 bool change_status = false; 192 bool change_status = false;
173 193
174 // Selectively send first few notifications only if number of downloads exceed 194 // Selectively send first few notifications only if number of downloads exceed
175 // kMaxDownloadsAtOnce. In that case, we also retain the infobar instance and 195 // kMaxDownloadsAtOnce. In that case, we also retain the infobar instance and
176 // don't close it. If allow is false, we send all the notifications to cancel 196 // don't close it. If allow is false, we send all the notifications to cancel
177 // all remaining downloads and close the infobar. 197 // all remaining downloads and close the infobar.
178 if (!allow || (callbacks_.size() < kMaxDownloadsAtOnce)) { 198 if (!allow || (callbacks_.size() < kMaxDownloadsAtOnce)) {
179 if (infobar_) { 199 if (infobar_) {
180 // Reset the delegate so we don't get notified again. 200 // Reset the delegate so we don't get notified again.
181 infobar_->set_host(NULL); 201 infobar_->set_host(NULL);
182 infobar_ = NULL; 202 infobar_ = NULL;
183 } 203 }
184 callbacks.swap(callbacks_); 204 callbacks.swap(callbacks_);
185 } else { 205 } else {
186 std::vector<DownloadRequestLimiter::Callback>::iterator start, end; 206 std::vector<DownloadRequestLimiter::Callback>::iterator start, end;
187 start = callbacks_.begin(); 207 start = callbacks_.begin();
188 end = callbacks_.begin() + kMaxDownloadsAtOnce; 208 end = callbacks_.begin() + kMaxDownloadsAtOnce;
189 callbacks.assign(start, end); 209 callbacks.assign(start, end);
190 callbacks_.erase(start, end); 210 callbacks_.erase(start, end);
191 change_status = true; 211 change_status = true;
192 } 212 }
193 213
194 for (size_t i = 0; i < callbacks.size(); ++i) 214 for (size_t i = 0; i < callbacks.size(); ++i)
195 host_->ScheduleNotification(callbacks[i], allow); 215 host_->ScheduleNotification(callbacks[i], allow);
196 216
197 if (change_status) 217 if (change_status)
198 status_ = DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD; 218 set_download_status(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD);
199 } 219 }
200 220
201 // DownloadRequestLimiter ------------------------------------------------------ 221 // DownloadRequestLimiter ------------------------------------------------------
202 222
203 DownloadRequestLimiter::DownloadRequestLimiter() { 223 DownloadRequestLimiter::DownloadRequestLimiter() {
204 } 224 }
205 225
206 DownloadRequestLimiter::~DownloadRequestLimiter() { 226 DownloadRequestLimiter::~DownloadRequestLimiter() {
207 // All the tabs should have closed before us, which sends notification and 227 // All the tabs should have closed before us, which sends notification and
208 // removes from state_map_. As such, there should be no pending callbacks. 228 // removes from state_map_. As such, there should be no pending callbacks.
209 DCHECK(state_map_.empty()); 229 DCHECK(state_map_.empty());
210 } 230 }
211 231
212 DownloadRequestLimiter::DownloadStatus 232 DownloadRequestLimiter::DownloadStatus
213 DownloadRequestLimiter::GetDownloadStatus(WebContents* tab) { 233 DownloadRequestLimiter::GetDownloadStatus(WebContents* web_contents) {
214 TabDownloadState* state = GetDownloadState(&tab->GetController(), NULL, false) ; 234 TabDownloadState* state = GetDownloadState(web_contents, NULL, false);
215 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD; 235 return state ? state->download_status() : ALLOW_ONE_DOWNLOAD;
216 } 236 }
217 237
218 void DownloadRequestLimiter::CanDownloadOnIOThread( 238 void DownloadRequestLimiter::CanDownloadOnIOThread(
219 int render_process_host_id, 239 int render_process_host_id,
220 int render_view_id, 240 int render_view_id,
221 int request_id, 241 int request_id,
222 const std::string& request_method, 242 const std::string& request_method,
223 const Callback& callback) { 243 const Callback& callback) {
224 // This is invoked on the IO thread. Schedule the task to run on the UI 244 // This is invoked on the IO thread. Schedule the task to run on the UI
225 // thread so that we can query UI state. 245 // thread so that we can query UI state.
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 246 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
227 BrowserThread::PostTask( 247 BrowserThread::PostTask(
228 BrowserThread::UI, FROM_HERE, 248 BrowserThread::UI, FROM_HERE,
229 base::Bind(&DownloadRequestLimiter::CanDownload, this, 249 base::Bind(&DownloadRequestLimiter::CanDownload, this,
230 render_process_host_id, render_view_id, request_id, 250 render_process_host_id, render_view_id, request_id,
231 request_method, callback)); 251 request_method, callback));
232 } 252 }
233 253
234 void DownloadRequestLimiter::OnUserGesture(WebContents* tab) {
235 TabDownloadState* state =
236 GetDownloadState(&tab->GetController(), NULL, false);
237 if (!state)
238 return;
239
240 state->OnUserGesture();
241 }
242
243 // static 254 // static
244 void DownloadRequestLimiter::SetTestingDelegate(TestingDelegate* delegate) { 255 void DownloadRequestLimiter::SetTestingDelegate(TestingDelegate* delegate) {
245 delegate_ = delegate; 256 delegate_ = delegate;
246 } 257 }
247 258
248 DownloadRequestLimiter::TabDownloadState* DownloadRequestLimiter:: 259 DownloadRequestLimiter::TabDownloadState*
249 GetDownloadState(NavigationController* controller, 260 DownloadRequestLimiter::GetDownloadState(
250 NavigationController* originating_controller, 261 WebContents* web_contents,
251 bool create) { 262 WebContents* originating_web_contents,
252 DCHECK(controller); 263 bool create) {
253 StateMap::iterator i = state_map_.find(controller); 264 DCHECK(web_contents);
265 StateMap::iterator i = state_map_.find(web_contents);
254 if (i != state_map_.end()) 266 if (i != state_map_.end())
255 return i->second; 267 return i->second;
256 268
257 if (!create) 269 if (!create)
258 return NULL; 270 return NULL;
259 271
260 TabDownloadState* state = 272 TabDownloadState* state =
261 new TabDownloadState(this, controller, originating_controller); 273 new TabDownloadState(this, web_contents, originating_web_contents);
262 state_map_[controller] = state; 274 state_map_[web_contents] = state;
263 return state; 275 return state;
264 } 276 }
265 277
266 void DownloadRequestLimiter::CanDownload(int render_process_host_id, 278 void DownloadRequestLimiter::CanDownload(int render_process_host_id,
267 int render_view_id, 279 int render_view_id,
268 int request_id, 280 int request_id,
269 const std::string& request_method, 281 const std::string& request_method,
270 const Callback& callback) { 282 const Callback& callback) {
271 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
272 284
273 WebContents* originating_tab = 285 WebContents* originating_contents =
274 tab_util::GetWebContentsByID(render_process_host_id, render_view_id); 286 tab_util::GetWebContentsByID(render_process_host_id, render_view_id);
275 if (!originating_tab) { 287 if (!originating_contents) {
276 // The tab was closed, don't allow the download. 288 // The WebContents was closed, don't allow the download.
277 ScheduleNotification(callback, false); 289 ScheduleNotification(callback, false);
278 return; 290 return;
279 } 291 }
280 292
281 CanDownloadImpl( 293 CanDownloadImpl(
282 TabContentsWrapper::GetCurrentWrapperForContents(originating_tab), 294 originating_contents,
283 request_id, 295 request_id,
284 request_method, 296 request_method,
285 callback); 297 callback);
286 } 298 }
287 299
288 void DownloadRequestLimiter::CanDownloadImpl( 300 void DownloadRequestLimiter::CanDownloadImpl(WebContents* originating_contents,
289 TabContentsWrapper* originating_tab, 301 int request_id,
290 int request_id, 302 const std::string& request_method,
291 const std::string& request_method, 303 const Callback& callback) {
292 const Callback& callback) { 304 DCHECK(originating_contents);
293 DCHECK(originating_tab);
294 305
295 // FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order 306 // FYI: Chrome Frame overrides CanDownload in ExternalTabContainer in order
296 // to cancel the download operation in chrome and let the host browser 307 // to cancel the download operation in chrome and let the host browser
297 // take care of it. 308 // take care of it.
298 WebContents* tab = originating_tab->web_contents(); 309 if (originating_contents->GetDelegate() &&
299 if (tab->GetDelegate() && !tab->GetDelegate()->CanDownload( 310 !originating_contents->GetDelegate()->CanDownload(
300 tab->GetRenderViewHost(), request_id, request_method)) { 311 originating_contents->GetRenderViewHost(),
312 request_id,
313 request_method)) {
301 ScheduleNotification(callback, false); 314 ScheduleNotification(callback, false);
302 return; 315 return;
303 } 316 }
304 317
305 // If the tab requesting the download is a constrained popup that is not 318 // If the tab requesting the download is a constrained popup that is not
306 // shown, treat the request as if it came from the parent. 319 // shown, treat the request as if it came from the parent.
307 TabContentsWrapper* effective_wrapper = originating_tab; 320 WebContents* effective_contents = originating_contents;
308 if (effective_wrapper->blocked_content_tab_helper()->delegate()) { 321 TabContentsWrapper* originating_wrapper =
309 effective_wrapper = effective_wrapper->blocked_content_tab_helper()-> 322 TabContentsWrapper::GetCurrentWrapperForContents(originating_contents);
310 delegate()->GetConstrainingContentsWrapper(effective_wrapper); 323 if (originating_wrapper &&
324 originating_wrapper->blocked_content_tab_helper()->delegate()) {
325 effective_contents = originating_wrapper->blocked_content_tab_helper()->
326 delegate()->GetConstrainingContentsWrapper(originating_wrapper)->
327 web_contents();
311 } 328 }
312 329
313 TabDownloadState* state = GetDownloadState( 330 TabDownloadState* state = GetDownloadState(
314 &effective_wrapper->web_contents()->GetController(), 331 effective_contents, originating_contents, true);
315 &tab->GetController(), true);
316 switch (state->download_status()) { 332 switch (state->download_status()) {
317 case ALLOW_ALL_DOWNLOADS: 333 case ALLOW_ALL_DOWNLOADS:
318 if (state->download_count() && !(state->download_count() % 334 if (state->download_count() && !(state->download_count() %
319 DownloadRequestLimiter::kMaxDownloadsAtOnce)) 335 DownloadRequestLimiter::kMaxDownloadsAtOnce))
320 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); 336 state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
321 ScheduleNotification(callback, true); 337 ScheduleNotification(callback, true);
322 state->increment_download_count(); 338 state->increment_download_count();
323 break; 339 break;
324 340
325 case ALLOW_ONE_DOWNLOAD: 341 case ALLOW_ONE_DOWNLOAD:
326 state->set_download_status(PROMPT_BEFORE_DOWNLOAD); 342 state->set_download_status(PROMPT_BEFORE_DOWNLOAD);
327 ScheduleNotification(callback, true); 343 ScheduleNotification(callback, true);
328 break; 344 break;
329 345
330 case DOWNLOADS_NOT_ALLOWED: 346 case DOWNLOADS_NOT_ALLOWED:
331 ScheduleNotification(callback, false); 347 ScheduleNotification(callback, false);
332 break; 348 break;
333 349
334 case PROMPT_BEFORE_DOWNLOAD: 350 case PROMPT_BEFORE_DOWNLOAD:
335 state->PromptUserForDownload(effective_wrapper->web_contents(), callback); 351 state->PromptUserForDownload(effective_contents, callback);
336 state->increment_download_count(); 352 state->increment_download_count();
337 break; 353 break;
338 354
339 default: 355 default:
340 NOTREACHED(); 356 NOTREACHED();
341 } 357 }
342 } 358 }
343 359
344 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback, 360 void DownloadRequestLimiter::ScheduleNotification(const Callback& callback,
345 bool allow) { 361 bool allow) {
346 BrowserThread::PostTask( 362 BrowserThread::PostTask(
347 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow)); 363 BrowserThread::IO, FROM_HERE, base::Bind(callback, allow));
348 } 364 }
349 365
350 void DownloadRequestLimiter::Remove(TabDownloadState* state) { 366 void DownloadRequestLimiter::Remove(TabDownloadState* state) {
351 DCHECK(ContainsKey(state_map_, state->controller())); 367 DCHECK(ContainsKey(state_map_, state->web_contents()));
352 state_map_.erase(state->controller()); 368 state_map_.erase(state->web_contents());
353 delete state; 369 delete state;
354 } 370 }
355 371
356 // static 372 // static
357 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ = 373 DownloadRequestLimiter::TestingDelegate* DownloadRequestLimiter::delegate_ =
358 NULL; 374 NULL;
OLDNEW
« no previous file with comments | « chrome/browser/download/download_request_limiter.h ('k') | chrome/browser/download/download_request_limiter_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698