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

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

Issue 2689373003: Introduce ParallelDownloadJob. (Closed)
Patch Set: Make windows compiler happy. Created 3 years, 10 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
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 // File method ordering: Methods in this file are in the same order as 5 // File method ordering: Methods in this file are in the same order as
6 // in download_item_impl.h, with the following exception: The public 6 // in download_item_impl.h, with the following exception: The public
7 // interface Start is placed in chronological order with the other 7 // interface Start is placed in chronological order with the other
8 // (private) routines that together define a DownloadItem's state 8 // (private) routines that together define a DownloadItem's state
9 // transitions as the download progresses. See "Download progression 9 // transitions as the download progresses. See "Download progression
10 // cascade" later in this file. 10 // cascade" later in this file.
(...skipping 22 matching lines...) Expand all
33 #include "base/logging.h" 33 #include "base/logging.h"
34 #include "base/metrics/histogram_macros.h" 34 #include "base/metrics/histogram_macros.h"
35 #include "base/stl_util.h" 35 #include "base/stl_util.h"
36 #include "base/strings/string_util.h" 36 #include "base/strings/string_util.h"
37 #include "base/strings/stringprintf.h" 37 #include "base/strings/stringprintf.h"
38 #include "base/strings/utf_string_conversions.h" 38 #include "base/strings/utf_string_conversions.h"
39 #include "content/browser/download/download_create_info.h" 39 #include "content/browser/download/download_create_info.h"
40 #include "content/browser/download/download_file.h" 40 #include "content/browser/download/download_file.h"
41 #include "content/browser/download/download_interrupt_reasons_impl.h" 41 #include "content/browser/download/download_interrupt_reasons_impl.h"
42 #include "content/browser/download/download_item_impl_delegate.h" 42 #include "content/browser/download/download_item_impl_delegate.h"
43 #include "content/browser/download/download_job_factory.h"
43 #include "content/browser/download/download_net_log_parameters.h" 44 #include "content/browser/download/download_net_log_parameters.h"
44 #include "content/browser/download/download_request_handle.h" 45 #include "content/browser/download/download_request_handle.h"
45 #include "content/browser/download/download_stats.h" 46 #include "content/browser/download/download_stats.h"
47 #include "content/browser/download/download_url_job.h"
46 #include "content/browser/renderer_host/render_view_host_impl.h" 48 #include "content/browser/renderer_host/render_view_host_impl.h"
47 #include "content/browser/web_contents/web_contents_impl.h" 49 #include "content/browser/web_contents/web_contents_impl.h"
48 #include "content/public/browser/browser_context.h" 50 #include "content/public/browser/browser_context.h"
49 #include "content/public/browser/browser_thread.h" 51 #include "content/public/browser/browser_thread.h"
50 #include "content/public/browser/content_browser_client.h" 52 #include "content/public/browser/content_browser_client.h"
51 #include "content/public/browser/download_danger_type.h" 53 #include "content/public/browser/download_danger_type.h"
52 #include "content/public/browser/download_interrupt_reasons.h" 54 #include "content/public/browser/download_interrupt_reasons.h"
53 #include "content/public/browser/download_url_parameters.h" 55 #include "content/public/browser/download_url_parameters.h"
54 #include "content/public/browser/storage_partition.h" 56 #include "content/public/browser/storage_partition.h"
55 #include "content/public/common/content_features.h" 57 #include "content/public/common/content_features.h"
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // Constructing for the "Save Page As..." feature: 232 // Constructing for the "Save Page As..." feature:
231 DownloadItemImpl::DownloadItemImpl( 233 DownloadItemImpl::DownloadItemImpl(
232 DownloadItemImplDelegate* delegate, 234 DownloadItemImplDelegate* delegate,
233 uint32_t download_id, 235 uint32_t download_id,
234 const base::FilePath& path, 236 const base::FilePath& path,
235 const GURL& url, 237 const GURL& url,
236 const std::string& mime_type, 238 const std::string& mime_type,
237 std::unique_ptr<DownloadRequestHandleInterface> request_handle, 239 std::unique_ptr<DownloadRequestHandleInterface> request_handle,
238 const net::NetLogWithSource& net_log) 240 const net::NetLogWithSource& net_log)
239 : is_save_package_download_(true), 241 : is_save_package_download_(true),
240 request_handle_(std::move(request_handle)),
241 guid_(base::ToUpperASCII(base::GenerateGUID())), 242 guid_(base::ToUpperASCII(base::GenerateGUID())),
242 download_id_(download_id), 243 download_id_(download_id),
243 target_path_(path), 244 target_path_(path),
244 url_chain_(1, url), 245 url_chain_(1, url),
245 mime_type_(mime_type), 246 mime_type_(mime_type),
246 original_mime_type_(mime_type), 247 original_mime_type_(mime_type),
247 start_tick_(base::TimeTicks::Now()), 248 start_tick_(base::TimeTicks::Now()),
248 state_(IN_PROGRESS_INTERNAL), 249 state_(IN_PROGRESS_INTERNAL),
249 start_time_(base::Time::Now()), 250 start_time_(base::Time::Now()),
250 delegate_(delegate), 251 delegate_(delegate),
251 current_path_(path), 252 current_path_(path),
252 net_log_(net_log), 253 net_log_(net_log),
253 weak_ptr_factory_(this) { 254 weak_ptr_factory_(this) {
255 job_ = base::MakeUnique<DownloadUrlJob>(std::move(request_handle));
256 job_->Attach(this);
257
254 delegate_->Attach(); 258 delegate_->Attach();
255 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS); 259 Init(true /* actively downloading */, SRC_SAVE_PAGE_AS);
256 } 260 }
257 261
258 DownloadItemImpl::~DownloadItemImpl() { 262 DownloadItemImpl::~DownloadItemImpl() {
259 DCHECK_CURRENTLY_ON(BrowserThread::UI); 263 DCHECK_CURRENTLY_ON(BrowserThread::UI);
260 264
261 // Should always have been nuked before now, at worst in 265 // Should always have been nuked before now, at worst in
262 // DownloadManager shutdown. 266 // DownloadManager shutdown.
263 DCHECK(!download_file_.get()); 267 DCHECK(!download_file_.get());
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 case RESUMING_INTERNAL: 364 case RESUMING_INTERNAL:
361 // No active request. 365 // No active request.
362 // TODO(asanka): In the case of RESUMING_INTERNAL, consider setting 366 // TODO(asanka): In the case of RESUMING_INTERNAL, consider setting
363 // is_paused_ even if there's no request currently associated with this 367 // is_paused_ even if there's no request currently associated with this
364 // DII. When a request is assigned (due to a resumption, for example) we 368 // DII. When a request is assigned (due to a resumption, for example) we
365 // can honor the is_paused_ setting. 369 // can honor the is_paused_ setting.
366 return; 370 return;
367 371
368 case IN_PROGRESS_INTERNAL: 372 case IN_PROGRESS_INTERNAL:
369 case TARGET_PENDING_INTERNAL: 373 case TARGET_PENDING_INTERNAL:
370 request_handle_->PauseRequest(); 374 job_->Pause();
371 is_paused_ = true; 375 is_paused_ = true;
asanka 2017/02/16 16:27:39 Consider removing is_paused_ and having the job_ k
xingliu 2017/02/20 18:59:10 Done. Makes sense.
372 UpdateObservers(); 376 UpdateObservers();
373 return; 377 return;
374 378
375 case MAX_DOWNLOAD_INTERNAL_STATE: 379 case MAX_DOWNLOAD_INTERNAL_STATE:
376 case TARGET_RESOLVED_INTERNAL: 380 case TARGET_RESOLVED_INTERNAL:
377 NOTREACHED(); 381 NOTREACHED();
378 } 382 }
379 } 383 }
380 384
381 void DownloadItemImpl::Resume() { 385 void DownloadItemImpl::Resume() {
382 DCHECK_CURRENTLY_ON(BrowserThread::UI); 386 DCHECK_CURRENTLY_ON(BrowserThread::UI);
383 DVLOG(20) << __func__ << "() download = " << DebugString(true); 387 DVLOG(20) << __func__ << "() download = " << DebugString(true);
384 switch (state_) { 388 switch (state_) {
385 case CANCELLED_INTERNAL: // Nothing to resume. 389 case CANCELLED_INTERNAL: // Nothing to resume.
386 case COMPLETE_INTERNAL: 390 case COMPLETE_INTERNAL:
387 case COMPLETING_INTERNAL: 391 case COMPLETING_INTERNAL:
388 case INITIAL_INTERNAL: 392 case INITIAL_INTERNAL:
389 case INTERRUPTED_TARGET_PENDING_INTERNAL: 393 case INTERRUPTED_TARGET_PENDING_INTERNAL:
390 case RESUMING_INTERNAL: // Resumption in progress. 394 case RESUMING_INTERNAL: // Resumption in progress.
391 return; 395 return;
392 396
393 case TARGET_PENDING_INTERNAL: 397 case TARGET_PENDING_INTERNAL:
394 case IN_PROGRESS_INTERNAL: 398 case IN_PROGRESS_INTERNAL:
395 if (!is_paused_) 399 if (!is_paused_)
396 return; 400 return;
397 request_handle_->ResumeRequest(); 401 job_->Resume();
398 is_paused_ = false; 402 is_paused_ = false;
399 UpdateObservers(); 403 UpdateObservers();
400 return; 404 return;
401 405
402 case INTERRUPTED_INTERNAL: 406 case INTERRUPTED_INTERNAL:
403 auto_resume_count_ = 0; // User input resets the counter. 407 auto_resume_count_ = 0; // User input resets the counter.
404 ResumeInterruptedDownload(ResumptionRequestSource::USER); 408 ResumeInterruptedDownload(ResumptionRequestSource::USER);
405 UpdateObservers(); 409 UpdateObservers();
406 return; 410 return;
407 411
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 769
766 BrowserContext* DownloadItemImpl::GetBrowserContext() const { 770 BrowserContext* DownloadItemImpl::GetBrowserContext() const {
767 return delegate_->GetBrowserContext(); 771 return delegate_->GetBrowserContext();
768 } 772 }
769 773
770 WebContents* DownloadItemImpl::GetWebContents() const { 774 WebContents* DownloadItemImpl::GetWebContents() const {
771 // TODO(rdsmith): Remove null check after removing GetWebContents() from 775 // TODO(rdsmith): Remove null check after removing GetWebContents() from
772 // paths that might be used by DownloadItems created from history import. 776 // paths that might be used by DownloadItems created from history import.
773 // Currently such items have null request_handle_s, where other items 777 // Currently such items have null request_handle_s, where other items
774 // (regular and SavePackage downloads) have actual objects off the pointer. 778 // (regular and SavePackage downloads) have actual objects off the pointer.
775 if (request_handle_) 779 if (job_)
776 return request_handle_->GetWebContents(); 780 return job_->GetWebContents();
777 return NULL; 781 return nullptr;
778 } 782 }
779 783
780 void DownloadItemImpl::OnContentCheckCompleted(DownloadDangerType danger_type) { 784 void DownloadItemImpl::OnContentCheckCompleted(DownloadDangerType danger_type) {
781 DCHECK_CURRENTLY_ON(BrowserThread::UI); 785 DCHECK_CURRENTLY_ON(BrowserThread::UI);
782 DCHECK(AllDataSaved()); 786 DCHECK(AllDataSaved());
783 787
784 // Danger type is only allowed to be set on an active download after all data 788 // Danger type is only allowed to be set on an active download after all data
785 // has been saved. This excludes all other states. In particular, 789 // has been saved. This excludes all other states. In particular,
786 // OnContentCheckCompleted() isn't allowed on an INTERRUPTED download since 790 // OnContentCheckCompleted() isn't allowed on an INTERRUPTED download since
787 // such an interruption would need to happen between OnAllDataSaved() and 791 // such an interruption would need to happen between OnAllDataSaved() and
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 // We're starting the download. 1169 // We're starting the download.
1166 void DownloadItemImpl::Start( 1170 void DownloadItemImpl::Start(
1167 std::unique_ptr<DownloadFile> file, 1171 std::unique_ptr<DownloadFile> file,
1168 std::unique_ptr<DownloadRequestHandleInterface> req_handle, 1172 std::unique_ptr<DownloadRequestHandleInterface> req_handle,
1169 const DownloadCreateInfo& new_create_info) { 1173 const DownloadCreateInfo& new_create_info) {
1170 DCHECK_CURRENTLY_ON(BrowserThread::UI); 1174 DCHECK_CURRENTLY_ON(BrowserThread::UI);
1171 DCHECK(!download_file_.get()); 1175 DCHECK(!download_file_.get());
1172 DVLOG(20) << __func__ << "() this=" << DebugString(true); 1176 DVLOG(20) << __func__ << "() this=" << DebugString(true);
1173 1177
1174 download_file_ = std::move(file); 1178 download_file_ = std::move(file);
1175 request_handle_ = std::move(req_handle); 1179 job_ = DownloadJobFactory::CreateJob(std::move(req_handle), new_create_info);
1176 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE; 1180 destination_error_ = DOWNLOAD_INTERRUPT_REASON_NONE;
1177 1181
1178 if (state_ == CANCELLED_INTERNAL) { 1182 if (state_ == CANCELLED_INTERNAL) {
1179 // The download was in the process of resuming when it was cancelled. Don't 1183 // The download was in the process of resuming when it was cancelled. Don't
1180 // proceed. 1184 // proceed.
1181 ReleaseDownloadFile(true); 1185 ReleaseDownloadFile(true);
1182 if (request_handle_) 1186 job_->Cancel(true);
1183 request_handle_->CancelRequest();
1184 return; 1187 return;
1185 } 1188 }
1186 1189
1187 // The state could be one of the following: 1190 // The state could be one of the following:
1188 // 1191 //
1189 // INITIAL_INTERNAL: A normal download attempt. 1192 // INITIAL_INTERNAL: A normal download attempt.
1190 // 1193 //
1191 // RESUMING_INTERNAL: A resumption attempt. May or may not have been 1194 // RESUMING_INTERNAL: A resumption attempt. May or may not have been
1192 // successful. 1195 // successful.
1193 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL); 1196 DCHECK(state_ == INITIAL_INTERNAL || state_ == RESUMING_INTERNAL);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 // interruption. Continue with current target path. 1228 // interruption. Continue with current target path.
1226 TransitionTo(TARGET_RESOLVED_INTERNAL); 1229 TransitionTo(TARGET_RESOLVED_INTERNAL);
1227 InterruptWithPartialState( 1230 InterruptWithPartialState(
1228 offset, std::move(hash_state), new_create_info.result); 1231 offset, std::move(hash_state), new_create_info.result);
1229 UpdateObservers(); 1232 UpdateObservers();
1230 return; 1233 return;
1231 } 1234 }
1232 1235
1233 // Successful download start. 1236 // Successful download start.
1234 DCHECK(download_file_.get()); 1237 DCHECK(download_file_.get());
1235 DCHECK(request_handle_.get()); 1238 DCHECK(job_.get());
1236 1239
1237 if (state_ == RESUMING_INTERNAL) 1240 if (state_ == RESUMING_INTERNAL)
1238 UpdateValidatorsOnResumption(new_create_info); 1241 UpdateValidatorsOnResumption(new_create_info);
1239 1242
1240 TransitionTo(TARGET_PENDING_INTERNAL); 1243 TransitionTo(TARGET_PENDING_INTERNAL);
1241 1244
1245 job_->Attach(this);
asanka 2017/02/16 16:27:39 Why is there a separate Attach() method? It would
xingliu 2017/02/20 18:59:10 Done. Move to pass the item in ctor.
1246 job_->Start();
1247 }
1248
1249 void DownloadItemImpl::InitializeDownloadFile() {
asanka 2017/02/16 16:27:39 This isn't so much initializing the download file,
xingliu 2017/02/20 18:59:10 Done, renamed to StartDownloadProgress.
1242 BrowserThread::PostTask( 1250 BrowserThread::PostTask(
1243 BrowserThread::FILE, FROM_HERE, 1251 BrowserThread::FILE, FROM_HERE,
1244 base::Bind(&DownloadFile::Initialize, 1252 base::Bind(&DownloadFile::Initialize,
1245 // Safe because we control download file lifetime. 1253 // Safe because we control download file lifetime.
1246 base::Unretained(download_file_.get()), 1254 base::Unretained(download_file_.get()),
1247 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized, 1255 base::Bind(&DownloadItemImpl::OnDownloadFileInitialized,
1248 weak_ptr_factory_.GetWeakPtr()))); 1256 weak_ptr_factory_.GetWeakPtr())));
1249 } 1257 }
1250 1258
1251 void DownloadItemImpl::OnDownloadFileInitialized( 1259 void DownloadItemImpl::OnDownloadFileInitialized(
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 1636
1629 if (current_path_.empty()) { 1637 if (current_path_.empty()) {
1630 hash_state_.reset(); 1638 hash_state_.reset();
1631 hash_.clear(); 1639 hash_.clear();
1632 received_bytes_ = 0; 1640 received_bytes_ = 0;
1633 } else { 1641 } else {
1634 UpdateProgress(bytes_so_far, 0); 1642 UpdateProgress(bytes_so_far, 0);
1635 SetHashState(std::move(hash_state)); 1643 SetHashState(std::move(hash_state));
1636 } 1644 }
1637 1645
1638 if (request_handle_) 1646 if (job_.get())
1639 request_handle_->CancelRequest(); 1647 job_->Cancel(false);
1640 1648
1641 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED || 1649 if (reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED ||
1642 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) { 1650 reason == DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN) {
1643 if (IsDangerous()) { 1651 if (IsDangerous()) {
1644 RecordDangerousDownloadDiscard( 1652 RecordDangerousDownloadDiscard(
1645 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED 1653 reason == DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
1646 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION 1654 ? DOWNLOAD_DISCARD_DUE_TO_USER_ACTION
1647 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN, 1655 : DOWNLOAD_DISCARD_DUE_TO_SHUTDOWN,
1648 GetDangerType(), GetTargetFilePath()); 1656 GetDangerType(), GetTargetFilePath());
1649 } 1657 }
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 case TARGET_RESOLVED_INTERNAL: 1777 case TARGET_RESOLVED_INTERNAL:
1770 case INTERRUPTED_TARGET_PENDING_INTERNAL: 1778 case INTERRUPTED_TARGET_PENDING_INTERNAL:
1771 break; 1779 break;
1772 1780
1773 case IN_PROGRESS_INTERNAL: 1781 case IN_PROGRESS_INTERNAL:
1774 DCHECK(!current_path_.empty()) << "Current output path must be known."; 1782 DCHECK(!current_path_.empty()) << "Current output path must be known.";
1775 DCHECK(!target_path_.empty()) << "Target path must be known."; 1783 DCHECK(!target_path_.empty()) << "Target path must be known.";
1776 DCHECK(current_path_.DirName() == target_path_.DirName()) 1784 DCHECK(current_path_.DirName() == target_path_.DirName())
1777 << "Current output directory must match target directory."; 1785 << "Current output directory must match target directory.";
1778 DCHECK(download_file_) << "Output file must be owned by download item."; 1786 DCHECK(download_file_) << "Output file must be owned by download item.";
1779 DCHECK(request_handle_) << "Download source must be active."; 1787 DCHECK(job_) << "Must have active download job.";
1780 DCHECK(!is_paused_) << "At the time a download enters IN_PROGRESS state, " 1788 DCHECK(!is_paused_) << "At the time a download enters IN_PROGRESS state, "
1781 "it must not be paused."; 1789 "it must not be paused.";
1782 break; 1790 break;
1783 1791
1784 case COMPLETING_INTERNAL: 1792 case COMPLETING_INTERNAL:
1785 DCHECK(all_data_saved_) << "All data must be saved prior to completion."; 1793 DCHECK(all_data_saved_) << "All data must be saved prior to completion.";
1786 DCHECK(!download_file_) 1794 DCHECK(!download_file_)
1787 << "Download file must be released prior to completion."; 1795 << "Download file must be released prior to completion.";
1788 DCHECK(!target_path_.empty()) << "Target path must be known."; 1796 DCHECK(!target_path_.empty()) << "Target path must be known.";
1789 DCHECK(current_path_ == target_path_) 1797 DCHECK(current_path_ == target_path_)
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2120 case RESUME_MODE_USER_CONTINUE: 2128 case RESUME_MODE_USER_CONTINUE:
2121 return "USER_CONTINUE"; 2129 return "USER_CONTINUE";
2122 case RESUME_MODE_USER_RESTART: 2130 case RESUME_MODE_USER_RESTART:
2123 return "USER_RESTART"; 2131 return "USER_RESTART";
2124 } 2132 }
2125 NOTREACHED() << "Unknown resume mode " << mode; 2133 NOTREACHED() << "Unknown resume mode " << mode;
2126 return "unknown"; 2134 return "unknown";
2127 } 2135 }
2128 2136
2129 } // namespace content 2137 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698