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

Side by Side Diff: content/browser/download/download_resource_handler.cc

Issue 10392111: Use ByteStream in downloads system to decouple source and sink. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added some histogram statistics. Created 8 years, 7 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 "content/browser/download/download_resource_handler.h" 5 #include "content/browser/download/download_resource_handler.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/message_loop_proxy.h"
11 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
12 #include "base/metrics/stats_counters.h" 13 #include "base/metrics/stats_counters.h"
13 #include "base/stringprintf.h" 14 #include "base/stringprintf.h"
14 #include "content/browser/download/download_buffer.h"
15 #include "content/browser/download/download_create_info.h" 15 #include "content/browser/download/download_create_info.h"
16 #include "content/browser/download/download_file_manager.h" 16 #include "content/browser/download/download_file_manager.h"
17 #include "content/browser/download/download_interrupt_reasons_impl.h" 17 #include "content/browser/download/download_interrupt_reasons_impl.h"
18 #include "content/browser/download/download_manager_impl.h" 18 #include "content/browser/download/download_manager_impl.h"
19 #include "content/browser/download/download_request_handle.h" 19 #include "content/browser/download/download_request_handle.h"
20 #include "content/browser/download/byte_stream.h"
20 #include "content/browser/download/download_stats.h" 21 #include "content/browser/download/download_stats.h"
21 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 22 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
22 #include "content/browser/renderer_host/resource_request_info_impl.h" 23 #include "content/browser/renderer_host/resource_request_info_impl.h"
23 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/download_interrupt_reasons.h" 25 #include "content/public/browser/download_interrupt_reasons.h"
25 #include "content/public/browser/download_item.h" 26 #include "content/public/browser/download_item.h"
26 #include "content/public/browser/download_manager_delegate.h" 27 #include "content/public/browser/download_manager_delegate.h"
27 #include "content/public/common/resource_response.h" 28 #include "content/public/common/resource_response.h"
28 #include "net/base/io_buffer.h" 29 #include "net/base/io_buffer.h"
29 #include "net/base/net_errors.h" 30 #include "net/base/net_errors.h"
30 #include "net/http/http_response_headers.h" 31 #include "net/http/http_response_headers.h"
31 #include "net/url_request/url_request_context.h" 32 #include "net/url_request/url_request_context.h"
32 33
33 using content::BrowserThread; 34 using content::BrowserThread;
34 using content::DownloadId; 35 using content::DownloadId;
35 using content::DownloadItem; 36 using content::DownloadItem;
36 using content::DownloadManager; 37 using content::DownloadManager;
37 using content::ResourceDispatcherHostImpl; 38 using content::ResourceDispatcherHostImpl;
38 using content::ResourceRequestInfoImpl; 39 using content::ResourceRequestInfoImpl;
39 40
40 namespace { 41 namespace {
41 42
43 static const int kDownloadPipeSize = 100 * 1024;
44
42 void CallStartedCBOnUIThread( 45 void CallStartedCBOnUIThread(
43 const DownloadResourceHandler::OnStartedCallback& started_cb, 46 const DownloadResourceHandler::OnStartedCallback& started_cb,
44 DownloadId id, 47 DownloadId id,
45 net::Error error) { 48 net::Error error) {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 49 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
47 if (started_cb.is_null()) 50 if (started_cb.is_null())
48 return; 51 return;
49 started_cb.Run(id, error); 52 started_cb.Run(id, error);
50 } 53 }
51 54
52 } // namespace 55 } // namespace
53 56
54 DownloadResourceHandler::DownloadResourceHandler( 57 DownloadResourceHandler::DownloadResourceHandler(
55 int render_process_host_id, 58 int render_process_host_id,
56 int render_view_id, 59 int render_view_id,
57 int request_id, 60 int request_id,
58 const GURL& url, 61 const GURL& url,
59 DownloadFileManager* download_file_manager, 62 DownloadFileManager* download_file_manager,
60 net::URLRequest* request, 63 net::URLRequest* request,
61 const DownloadResourceHandler::OnStartedCallback& started_cb, 64 const DownloadResourceHandler::OnStartedCallback& started_cb,
62 const content::DownloadSaveInfo& save_info) 65 const content::DownloadSaveInfo& save_info)
63 : download_id_(DownloadId::Invalid()), 66 : download_id_(DownloadId::Invalid()),
64 global_id_(render_process_host_id, request_id), 67 global_id_(render_process_host_id, request_id),
65 render_view_id_(render_view_id), 68 render_view_id_(render_view_id),
66 content_length_(0), 69 content_length_(0),
67 download_file_manager_(download_file_manager), 70 download_file_manager_(download_file_manager),
68 request_(request), 71 request_(request),
69 started_cb_(started_cb), 72 started_cb_(started_cb),
70 save_info_(save_info), 73 save_info_(save_info),
71 buffer_(new content::DownloadBuffer),
72 is_paused_(false),
73 last_buffer_size_(0), 74 last_buffer_size_(0),
74 bytes_read_(0) { 75 bytes_read_(0) {
75 download_stats::RecordDownloadCount(download_stats::UNTHROTTLED_COUNT); 76 download_stats::RecordDownloadCount(download_stats::UNTHROTTLED_COUNT);
76 } 77 }
77 78
78 bool DownloadResourceHandler::OnUploadProgress(int request_id, 79 bool DownloadResourceHandler::OnUploadProgress(int request_id,
79 uint64 position, 80 uint64 position,
80 uint64 size) { 81 uint64 size) {
81 return true; 82 return true;
82 } 83 }
(...skipping 30 matching lines...) Expand all
113 set_content_length(response->content_length); 114 set_content_length(response->content_length);
114 115
115 const ResourceRequestInfoImpl* request_info = 116 const ResourceRequestInfoImpl* request_info =
116 ResourceRequestInfoImpl::ForRequest(request_); 117 ResourceRequestInfoImpl::ForRequest(request_);
117 118
118 // Deleted in DownloadManager. 119 // Deleted in DownloadManager.
119 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo( 120 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo(
120 base::Time::Now(), 0, content_length_, DownloadItem::IN_PROGRESS, 121 base::Time::Now(), 0, content_length_, DownloadItem::IN_PROGRESS,
121 request_->net_log(), request_info->has_user_gesture(), 122 request_->net_log(), request_info->has_user_gesture(),
122 request_info->transition_type())); 123 request_info->transition_type()));
124
125 // Create the ByteStream pipe for sending data to the download sink.
126 scoped_ptr<content::ByteStreamOutput> pipe_output;
127 CreateByteStream(
128 base::MessageLoopProxy::current(),
129 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE),
130 kDownloadPipeSize, &pipe_input_, &pipe_output);
131 pipe_input_->RegisterCallback(
132 // We're refcounted, so this is a safe callback to pass around.
133 base::Bind(&DownloadResourceHandler::ResumeRequest, this));
134
123 info->url_chain = request_->url_chain(); 135 info->url_chain = request_->url_chain();
124 info->referrer_url = GURL(request_->referrer()); 136 info->referrer_url = GURL(request_->referrer());
125 info->start_time = base::Time::Now(); 137 info->start_time = base::Time::Now();
126 info->received_bytes = save_info_.offset; 138 info->received_bytes = save_info_.offset;
127 info->total_bytes = content_length_; 139 info->total_bytes = content_length_;
128 info->state = DownloadItem::IN_PROGRESS; 140 info->state = DownloadItem::IN_PROGRESS;
129 info->has_user_gesture = request_info->has_user_gesture(); 141 info->has_user_gesture = request_info->has_user_gesture();
130 info->content_disposition = content_disposition_; 142 info->content_disposition = content_disposition_;
131 info->mime_type = response->mime_type; 143 info->mime_type = response->mime_type;
132 info->remote_address = request_->GetSocketAddress().host(); 144 info->remote_address = request_->GetSocketAddress().host();
(...skipping 24 matching lines...) Expand all
157 "Accept-Ranges", 169 "Accept-Ranges",
158 &accept_ranges_)) { 170 &accept_ranges_)) {
159 accept_ranges_ = ""; 171 accept_ranges_ = "";
160 } 172 }
161 173
162 info->prompt_user_for_save_location = 174 info->prompt_user_for_save_location =
163 save_info_.prompt_for_save_location && save_info_.file_path.empty(); 175 save_info_.prompt_for_save_location && save_info_.file_path.empty();
164 info->referrer_charset = request_->context()->referrer_charset(); 176 info->referrer_charset = request_->context()->referrer_charset();
165 info->save_info = save_info_; 177 info->save_info = save_info_;
166 178
167
168 BrowserThread::PostTask( 179 BrowserThread::PostTask(
169 BrowserThread::UI, FROM_HERE, 180 BrowserThread::UI, FROM_HERE,
170 base::Bind(&DownloadResourceHandler::StartOnUIThread, this, 181 base::Bind(&DownloadResourceHandler::StartOnUIThread, this,
171 base::Passed(&info), request_handle)); 182 base::Passed(info.Pass()),
172 183 base::Passed(pipe_output.Pass()),
173 // We can't start saving the data before we create the file on disk and have a 184 request_handle));
174 // download id. The request will be un-paused in
175 // DownloadFileManager::CreateDownloadFile.
176 ResourceDispatcherHostImpl::Get()->PauseRequest(global_id_.child_id,
177 global_id_.request_id,
178 true);
179 185
180 return true; 186 return true;
181 } 187 }
182 188
183 void DownloadResourceHandler::CallStartedCB(DownloadId id, net::Error error) { 189 void DownloadResourceHandler::CallStartedCB(DownloadId id, net::Error error) {
184 if (started_cb_.is_null()) 190 if (started_cb_.is_null())
185 return; 191 return;
186 BrowserThread::PostTask( 192 BrowserThread::PostTask(
187 BrowserThread::UI, FROM_HERE, 193 BrowserThread::UI, FROM_HERE,
188 base::Bind(&CallStartedCBOnUIThread, started_cb_, id, error)); 194 base::Bind(&CallStartedCBOnUIThread, started_cb_, id, error));
(...skipping 15 matching lines...) Expand all
204 *buf_size = min_size < 0 ? kReadBufSize : min_size; 210 *buf_size = min_size < 0 ? kReadBufSize : min_size;
205 last_buffer_size_ = *buf_size; 211 last_buffer_size_ = *buf_size;
206 read_buffer_ = new net::IOBuffer(*buf_size); 212 read_buffer_ = new net::IOBuffer(*buf_size);
207 } 213 }
208 *buf = read_buffer_.get(); 214 *buf = read_buffer_.get();
209 return true; 215 return true;
210 } 216 }
211 217
212 // Pass the buffer to the download file writer. 218 // Pass the buffer to the download file writer.
213 bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { 219 bool DownloadResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
220 if (!read_buffer_) {
benjhayden 2012/05/21 14:36:45 Could Darin review the ResourceHandler-related par
Randy Smith (Not in Mondays) 2012/05/23 03:33:15 Sure, I'll ask him. Even if he does, though, I'd
221 // Ignore spurious OnReadCompleted! PauseRequest(true) called from within
222 // OnReadCompleted tells the ResourceDispatcherHost that we did not consume
223 // the data. PauseRequest(false) then repeats the last OnReadCompleted
224 // call. We pause the request after we transmit the buffer onwards, so
225 // the ResourceDispatcherHost pause mechanism does not fit our use
226 // case very well.
227 // Note that this test makes redundant the DCHECK() below; it's being left
228 // in in hopes that the TODO will be executed soon.
229 // TODO(darin): Fix the ResourceDispatcherHost to avoid this hack!
230 return true;
231 }
232
214 base::TimeTicks now(base::TimeTicks::Now()); 233 base::TimeTicks now(base::TimeTicks::Now());
215 if (!last_read_time_.is_null()) { 234 if (!last_read_time_.is_null()) {
216 double seconds_since_last_read = (now - last_read_time_).InSecondsF(); 235 double seconds_since_last_read = (now - last_read_time_).InSecondsF();
217 if (now == last_read_time_) 236 if (now == last_read_time_)
218 // Use 1/10 ms as a "very small number" so that we avoid 237 // Use 1/10 ms as a "very small number" so that we avoid
219 // divide-by-zero error and still record a very high potential bandwidth. 238 // divide-by-zero error and still record a very high potential bandwidth.
220 seconds_since_last_read = 0.00001; 239 seconds_since_last_read = 0.00001;
221 240
222 double actual_bandwidth = (*bytes_read)/seconds_since_last_read; 241 double actual_bandwidth = (*bytes_read)/seconds_since_last_read;
223 double potential_bandwidth = last_buffer_size_/seconds_since_last_read; 242 double potential_bandwidth = last_buffer_size_/seconds_since_last_read;
224 download_stats::RecordBandwidth(actual_bandwidth, potential_bandwidth); 243 download_stats::RecordBandwidth(actual_bandwidth, potential_bandwidth);
225 } 244 }
226 last_read_time_ = now; 245 last_read_time_ = now;
227 246
228 if (!*bytes_read) 247 if (!*bytes_read)
229 return true; 248 return true;
230 bytes_read_ += *bytes_read; 249 bytes_read_ += *bytes_read;
231 DCHECK(read_buffer_); 250 DCHECK(read_buffer_);
232 // Swap the data.
233 net::IOBuffer* io_buffer = NULL;
234 read_buffer_.swap(&io_buffer);
235 size_t vector_size = buffer_->AddData(io_buffer, *bytes_read);
236 bool need_update = (vector_size == 1); // Buffer was empty.
237 251
238 // We are passing ownership of this buffer to the download file manager. 252 // Take the data ship it down the pipe. If the pipe is full, pause the
239 if (need_update) { 253 // request; the pipe callback will resume it.
240 BrowserThread::PostTask( 254 if (!pipe_input_->Write(read_buffer_, *bytes_read)) {
241 BrowserThread::FILE, FROM_HERE, 255 ResourceDispatcherHostImpl::Get()->PauseRequest(global_id_.child_id,
242 base::Bind(&DownloadFileManager::UpdateDownload, 256 global_id_.request_id,
243 download_file_manager_, download_id_, buffer_)); 257 true);
258 last_pause_time_ = now;
244 } 259 }
245 260
246 // We schedule a pause outside of the read loop if there is too much file 261 read_buffer_ = NULL; // Drop our reference.
247 // writing work to do.
248 if (vector_size > kLoadsToWrite)
249 StartPauseTimer();
250 262
251 return true; 263 return true;
252 } 264 }
253 265
254 bool DownloadResourceHandler::OnResponseCompleted( 266 bool DownloadResourceHandler::OnResponseCompleted(
255 int request_id, 267 int request_id,
256 const net::URLRequestStatus& status, 268 const net::URLRequestStatus& status,
257 const std::string& security_info) { 269 const std::string& security_info) {
258 VLOG(20) << __FUNCTION__ << "()" << DebugString() 270 VLOG(20) << __FUNCTION__ << "()" << DebugString()
259 << " request_id = " << request_id 271 << " request_id = " << request_id
260 << " status.status() = " << status.status() 272 << " status.status() = " << status.status()
261 << " status.error() = " << status.error(); 273 << " status.error() = " << status.error();
262 int response = status.is_success() ? request_->GetResponseCode() : 0; 274 int response = status.is_success() ? request_->GetResponseCode() : 0;
263 if (download_id_.IsValid()) { 275 if (download_id_.IsValid()) {
264 OnResponseCompletedInternal(request_id, status, security_info, response); 276 OnResponseCompletedInternal(request_id, status, security_info, response);
265 } else { 277 } else {
266 // We got cancelled before the task which sets the id ran on the IO thread. 278 // We got cancelled before the task which sets the id ran on the IO thread.
267 // Wait for it. 279 // Wait for it.
268 BrowserThread::PostTaskAndReply( 280 BrowserThread::PostTaskAndReply(
269 BrowserThread::UI, FROM_HERE, 281 BrowserThread::UI, FROM_HERE,
270 base::Bind(&base::DoNothing), 282 base::Bind(&base::DoNothing),
271 base::Bind(&DownloadResourceHandler::OnResponseCompletedInternal, this, 283 base::Bind(&DownloadResourceHandler::OnResponseCompletedInternal, this,
272 request_id, status, security_info, response)); 284 request_id, status, security_info, response));
273 } 285 }
274 // Can't trust request_ being value after this point. 286 // Can't trust request_ being value after this point.
275 request_ = NULL; 287 request_ = NULL;
288
289 // Stats
290 download_stats::RecordNetworkBandwidth(
291 bytes_read_, base::TimeTicks::Now() - download_start_time_,
292 total_pause_time_);
293
276 return true; 294 return true;
277 } 295 }
278 296
279 void DownloadResourceHandler::OnResponseCompletedInternal( 297 void DownloadResourceHandler::OnResponseCompletedInternal(
280 int request_id, 298 int request_id,
281 const net::URLRequestStatus& status, 299 const net::URLRequestStatus& status,
282 const std::string& security_info, 300 const std::string& security_info,
283 int response_code) { 301 int response_code) {
284 // NOTE: |request_| may be a dangling pointer at this point. 302 // NOTE: |request_| may be a dangling pointer at this point.
285 VLOG(20) << __FUNCTION__ << "()" 303 VLOG(20) << __FUNCTION__ << "()"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 break; 343 break;
326 } 344 }
327 } 345 }
328 } 346 }
329 347
330 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_); 348 download_stats::RecordAcceptsRanges(accept_ranges_, bytes_read_);
331 349
332 // If the callback was already run on the UI thread, this will be a noop. 350 // If the callback was already run on the UI thread, this will be a noop.
333 CallStartedCB(download_id_, error_code); 351 CallStartedCB(download_id_, error_code);
334 352
335 // We transfer ownership to |DownloadFileManager| to delete |buffer_|, 353 // Send the info down the pipe. Conditional is in case we get
336 // so that any functions queued up on the FILE thread are executed 354 // OnResponseCompleted without OnResponseStarted.
337 // before deletion. 355 if (pipe_input_.get())
338 BrowserThread::PostTask( 356 pipe_input_->Close(reason);
339 BrowserThread::FILE, FROM_HERE, 357
340 base::Bind(&DownloadFileManager::OnResponseCompleted, 358 pipe_input_.reset(); // We no longer need the pipe.
341 download_file_manager_, download_id_, reason, security_info));
342 buffer_ = NULL; // The buffer is longer needed by |DownloadResourceHandler|.
343 read_buffer_ = NULL; 359 read_buffer_ = NULL;
344 } 360 }
345 361
346 void DownloadResourceHandler::OnRequestClosed() { 362 void DownloadResourceHandler::OnRequestClosed() {
347 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration", 363 UMA_HISTOGRAM_TIMES("SB2.DownloadDuration",
348 base::TimeTicks::Now() - download_start_time_); 364 base::TimeTicks::Now() - download_start_time_);
349 } 365 }
350 366
351 void DownloadResourceHandler::StartOnUIThread( 367 void DownloadResourceHandler::StartOnUIThread(
352 scoped_ptr<DownloadCreateInfo> info, 368 scoped_ptr<DownloadCreateInfo> info,
369 scoped_ptr<content::ByteStreamOutput> pipe,
353 const DownloadRequestHandle& handle) { 370 const DownloadRequestHandle& handle) {
354 DownloadManager* download_manager = handle.GetDownloadManager(); 371 DownloadManager* download_manager = handle.GetDownloadManager();
355 if (!download_manager) { 372 if (!download_manager) {
356 // NULL in unittests or if the page closed right after starting the 373 // NULL in unittests or if the page closed right after starting the
357 // download. 374 // download.
358 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED); 375 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED);
359 return; 376 return;
360 } 377 }
361 DownloadId download_id = download_manager->delegate()->GetNextId(); 378 DownloadId download_id = download_manager->delegate()->GetNextId();
362 info->download_id = download_id; 379 info->download_id = download_id;
363 BrowserThread::PostTask( 380 BrowserThread::PostTask(
364 BrowserThread::IO, FROM_HERE, 381 BrowserThread::IO, FROM_HERE,
365 base::Bind(&DownloadResourceHandler::set_download_id, this, 382 base::Bind(&DownloadResourceHandler::set_download_id, this,
366 info->download_id)); 383 info->download_id));
367 // It's safe to continue on with download initiation before we have 384 // It's safe to continue on with download initiation before we have
368 // confirmation that that download_id_ has been set on the IO thread, as any 385 // confirmation that that download_id_ has been set on the IO thread, as any
369 // messages generated by the UI thread that affect the IO thread will be 386 // messages generated by the UI thread that affect the IO thread will be
370 // behind the message posted above. 387 // behind the message posted above.
371 download_file_manager_->StartDownload(info.release(), handle); 388 download_file_manager_->StartDownload(info.Pass(), pipe.Pass(), handle);
372 CallStartedCB(download_id, net::OK); 389 CallStartedCB(download_id, net::OK);
373 } 390 }
374 391
375 void DownloadResourceHandler::set_download_id(content::DownloadId id) { 392 void DownloadResourceHandler::set_download_id(content::DownloadId id) {
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
377 download_id_ = id; 394 download_id_ = id;
378 } 395 }
379 396
380 // If the content-length header is not present (or contains something other 397 // If the content-length header is not present (or contains something other
381 // than numbers), the incoming content_length is -1 (unknown size). 398 // than numbers), the incoming content_length is -1 (unknown size).
382 // Set the content length to 0 to indicate unknown size to DownloadManager. 399 // Set the content length to 0 to indicate unknown size to DownloadManager.
383 void DownloadResourceHandler::set_content_length(const int64& content_length) { 400 void DownloadResourceHandler::set_content_length(const int64& content_length) {
384 content_length_ = 0; 401 content_length_ = 0;
385 if (content_length > 0) 402 if (content_length > 0)
386 content_length_ = content_length; 403 content_length_ = content_length;
387 } 404 }
388 405
389 void DownloadResourceHandler::set_content_disposition( 406 void DownloadResourceHandler::set_content_disposition(
390 const std::string& content_disposition) { 407 const std::string& content_disposition) {
391 content_disposition_ = content_disposition; 408 content_disposition_ = content_disposition;
392 } 409 }
393 410
394 void DownloadResourceHandler::CheckWriteProgress() {
395 if (!buffer_.get())
396 return; // The download completed while we were waiting to run.
397
398 size_t contents_size = buffer_->size();
399
400 bool should_pause = contents_size > kLoadsToWrite;
401
402 // We'll come back later and see if it's okay to unpause the request.
403 if (should_pause)
404 StartPauseTimer();
405
406 if (is_paused_ != should_pause) {
407 ResourceDispatcherHostImpl::Get()->PauseRequest(global_id_.child_id,
408 global_id_.request_id,
409 should_pause);
410 is_paused_ = should_pause;
411 }
412 }
413
414 DownloadResourceHandler::~DownloadResourceHandler() { 411 DownloadResourceHandler::~DownloadResourceHandler() {
415 // This won't do anything if the callback was called before. 412 // This won't do anything if the callback was called before.
416 // If it goes through, it will likely be because OnWillStart() returned 413 // If it goes through, it will likely be because OnWillStart() returned
417 // false somewhere in the chain of resource handlers. 414 // false somewhere in the chain of resource handlers.
418 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED); 415 CallStartedCB(download_id_, net::ERR_ACCESS_DENIED);
416
417 // Remove output pipe callback if a pipe exists.
418 if (pipe_input_.get())
419 pipe_input_->RegisterCallback(base::Closure());
419 } 420 }
420 421
421 void DownloadResourceHandler::StartPauseTimer() { 422 void DownloadResourceHandler::ResumeRequest() {
422 if (!pause_timer_.IsRunning()) 423 ResourceDispatcherHostImpl::Get()->PauseRequest(global_id_.child_id,
423 pause_timer_.Start(FROM_HERE, 424 global_id_.request_id,
424 base::TimeDelta::FromMilliseconds(kThrottleTimeMs), this, 425 false);
425 &DownloadResourceHandler::CheckWriteProgress); 426 total_pause_time_ += (base::TimeTicks::Now() - last_pause_time_);
426 } 427 }
427 428
428 std::string DownloadResourceHandler::DebugString() const { 429 std::string DownloadResourceHandler::DebugString() const {
429 return base::StringPrintf("{" 430 return base::StringPrintf("{"
430 " url_ = " "\"%s\"" 431 " url_ = " "\"%s\""
431 " download_id_ = " "%d" 432 " download_id_ = " "%d"
432 " global_id_ = {" 433 " global_id_ = {"
433 " child_id = " "%d" 434 " child_id = " "%d"
434 " request_id = " "%d" 435 " request_id = " "%d"
435 " }" 436 " }"
436 " render_view_id_ = " "%d" 437 " render_view_id_ = " "%d"
437 " save_info_.file_path = \"%" PRFilePath "\"" 438 " save_info_.file_path = \"%" PRFilePath "\""
438 " }", 439 " }",
439 request_ ? 440 request_ ?
440 request_->url().spec().c_str() : 441 request_->url().spec().c_str() :
441 "<NULL request>", 442 "<NULL request>",
442 download_id_.local(), 443 download_id_.local(),
443 global_id_.child_id, 444 global_id_.child_id,
444 global_id_.request_id, 445 global_id_.request_id,
445 render_view_id_, 446 render_view_id_,
446 save_info_.file_path.value().c_str()); 447 save_info_.file_path.value().c_str());
447 } 448 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698