| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_item.h" | 5 #include "content/browser/download/download_item.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 // database handles in incognito mode starting at -1 and progressively getting | 117 // database handles in incognito mode starting at -1 and progressively getting |
| 118 // more negative. | 118 // more negative. |
| 119 // static | 119 // static |
| 120 const int DownloadItem::kUninitializedHandle = 0; | 120 const int DownloadItem::kUninitializedHandle = 0; |
| 121 | 121 |
| 122 const char DownloadItem::kEmptyFileHash[] = ""; | 122 const char DownloadItem::kEmptyFileHash[] = ""; |
| 123 | 123 |
| 124 // Constructor for reading from the history service. | 124 // Constructor for reading from the history service. |
| 125 DownloadItem::DownloadItem(DownloadManager* download_manager, | 125 DownloadItem::DownloadItem(DownloadManager* download_manager, |
| 126 const DownloadPersistentStoreInfo& info) | 126 const DownloadPersistentStoreInfo& info) |
| 127 : download_id_(download_manager->GetNextId()), | 127 : download_id_(info.local_id == -1 ? |
| 128 download_manager->GetNextId() : |
| 129 DownloadId(download_manager, info.local_id)), |
| 128 full_path_(info.path), | 130 full_path_(info.path), |
| 129 url_chain_(1, info.url), | 131 url_chain_(1, info.url), |
| 130 referrer_url_(info.referrer_url), | 132 referrer_url_(info.referrer_url), |
| 131 total_bytes_(info.total_bytes), | 133 total_bytes_(info.total_bytes), |
| 132 received_bytes_(info.received_bytes), | 134 received_bytes_(info.received_bytes), |
| 135 hash_(info.hash), |
| 136 last_modified_time_(info.last_modified_time), |
| 137 etag_(info.etag), |
| 138 last_reason_(info.last_reason), |
| 133 start_tick_(base::TimeTicks()), | 139 start_tick_(base::TimeTicks()), |
| 134 state_(static_cast<DownloadState>(info.state)), | 140 state_(static_cast<DownloadState>(info.state)), |
| 135 start_time_(info.start_time), | 141 start_time_(info.start_time), |
| 136 end_time_(info.end_time), | 142 end_time_(info.end_time), |
| 137 db_handle_(info.db_handle), | 143 db_handle_(info.db_handle), |
| 138 download_manager_(download_manager), | 144 download_manager_(download_manager), |
| 139 is_paused_(false), | 145 is_paused_(false), |
| 140 open_when_complete_(false), | 146 open_when_complete_(false), |
| 141 file_externally_removed_(false), | 147 file_externally_removed_(false), |
| 142 safety_state_(SAFE), | 148 safety_state_(SAFE), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 168 full_path_(info.path), | 174 full_path_(info.path), |
| 169 url_chain_(info.url_chain), | 175 url_chain_(info.url_chain), |
| 170 referrer_url_(info.referrer_url), | 176 referrer_url_(info.referrer_url), |
| 171 suggested_filename_(UTF16ToUTF8(info.save_info.suggested_name)), | 177 suggested_filename_(UTF16ToUTF8(info.save_info.suggested_name)), |
| 172 content_disposition_(info.content_disposition), | 178 content_disposition_(info.content_disposition), |
| 173 mime_type_(info.mime_type), | 179 mime_type_(info.mime_type), |
| 174 original_mime_type_(info.original_mime_type), | 180 original_mime_type_(info.original_mime_type), |
| 175 referrer_charset_(info.referrer_charset), | 181 referrer_charset_(info.referrer_charset), |
| 176 total_bytes_(info.total_bytes), | 182 total_bytes_(info.total_bytes), |
| 177 received_bytes_(0), | 183 received_bytes_(0), |
| 184 hash_(DownloadItem::kEmptyFileHash), |
| 185 last_modified_time_(info.last_modified), |
| 186 etag_(info.etag), |
| 178 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | 187 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), |
| 179 start_tick_(base::TimeTicks::Now()), | 188 start_tick_(base::TimeTicks::Now()), |
| 180 state_(IN_PROGRESS), | 189 state_(IN_PROGRESS), |
| 181 start_time_(info.start_time), | 190 start_time_(info.start_time), |
| 182 db_handle_(DownloadItem::kUninitializedHandle), | 191 db_handle_(DownloadItem::kUninitializedHandle), |
| 183 download_manager_(download_manager), | 192 download_manager_(download_manager), |
| 184 is_paused_(false), | 193 is_paused_(false), |
| 185 open_when_complete_(false), | 194 open_when_complete_(false), |
| 186 file_externally_removed_(false), | 195 file_externally_removed_(false), |
| 187 safety_state_(SAFE), | 196 safety_state_(SAFE), |
| 188 auto_opened_(false), | 197 auto_opened_(false), |
| 189 is_otr_(is_otr), | 198 is_otr_(is_otr), |
| 190 is_temporary_(!info.save_info.file_path.empty()), | 199 is_temporary_(!info.save_info.file_path.empty() && |
| 200 (info.received_bytes == 0)), |
| 191 all_data_saved_(false), | 201 all_data_saved_(false), |
| 192 opened_(false), | 202 opened_(false), |
| 193 open_enabled_(true), | 203 open_enabled_(true), |
| 194 delegate_delayed_complete_(false) { | 204 delegate_delayed_complete_(false) { |
| 195 Init(true /* actively downloading */); | 205 Init(true /* actively downloading */); |
| 196 } | 206 } |
| 197 | 207 |
| 198 // Constructing for the "Save Page As..." feature: | 208 // Constructing for the "Save Page As..." feature: |
| 199 DownloadItem::DownloadItem(DownloadManager* download_manager, | 209 DownloadItem::DownloadItem(DownloadManager* download_manager, |
| 200 const FilePath& path, | 210 const FilePath& path, |
| 201 const GURL& url, | 211 const GURL& url, |
| 202 bool is_otr, | 212 bool is_otr, |
| 203 DownloadId download_id) | 213 DownloadId download_id) |
| 204 : download_id_(download_id), | 214 : download_id_(download_id), |
| 205 full_path_(path), | 215 full_path_(path), |
| 206 url_chain_(1, url), | 216 url_chain_(1, url), |
| 207 referrer_url_(GURL()), | 217 referrer_url_(GURL()), |
| 208 total_bytes_(0), | 218 total_bytes_(0), |
| 209 received_bytes_(0), | 219 received_bytes_(0), |
| 220 hash_(DownloadItem::kEmptyFileHash), |
| 210 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), | 221 last_reason_(DOWNLOAD_INTERRUPT_REASON_NONE), |
| 211 start_tick_(base::TimeTicks::Now()), | 222 start_tick_(base::TimeTicks::Now()), |
| 212 state_(IN_PROGRESS), | 223 state_(IN_PROGRESS), |
| 213 start_time_(base::Time::Now()), | 224 start_time_(base::Time::Now()), |
| 214 db_handle_(DownloadItem::kUninitializedHandle), | 225 db_handle_(DownloadItem::kUninitializedHandle), |
| 215 download_manager_(download_manager), | 226 download_manager_(download_manager), |
| 216 is_paused_(false), | 227 is_paused_(false), |
| 217 open_when_complete_(false), | 228 open_when_complete_(false), |
| 218 file_externally_removed_(false), | 229 file_externally_removed_(false), |
| 219 safety_state_(SAFE), | 230 safety_state_(SAFE), |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated", | 324 UMA_HISTOGRAM_ENUMERATION("Download.DangerousDownloadValidated", |
| 314 GetDangerType(), | 325 GetDangerType(), |
| 315 DANGEROUS_TYPE_MAX); | 326 DANGEROUS_TYPE_MAX); |
| 316 | 327 |
| 317 safety_state_ = DANGEROUS_BUT_VALIDATED; | 328 safety_state_ = DANGEROUS_BUT_VALIDATED; |
| 318 UpdateObservers(); | 329 UpdateObservers(); |
| 319 | 330 |
| 320 download_manager_->MaybeCompleteDownload(this); | 331 download_manager_->MaybeCompleteDownload(this); |
| 321 } | 332 } |
| 322 | 333 |
| 323 void DownloadItem::UpdateSize(int64 bytes_so_far) { | 334 void DownloadItem::UpdateSizeAndHash(int64 bytes_so_far, |
| 335 const std::string& partial_hash) { |
| 324 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 336 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 325 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 337 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 326 | 338 |
| 339 if (!partial_hash.empty() && !BaseFile::IsEmptySha256Hash(partial_hash)) |
| 340 hash_ = partial_hash; |
| 341 |
| 327 received_bytes_ = bytes_so_far; | 342 received_bytes_ = bytes_so_far; |
| 328 | 343 |
| 329 // If we've received more data than we were expecting (bad server info?), | 344 // If we've received more data than we were expecting (bad server info?), |
| 330 // revert to 'unknown size mode'. | 345 // revert to 'unknown size mode'. |
| 331 if (received_bytes_ > total_bytes_) | 346 if (received_bytes_ > total_bytes_) |
| 332 total_bytes_ = 0; | 347 total_bytes_ = 0; |
| 333 } | 348 } |
| 334 | 349 |
| 335 // Updates from the download thread may have been posted while this download | 350 // Updates from the download thread may have been posted while this download |
| 336 // was being cancelled in the UI thread, so we'll accept them unless we're | 351 // was being cancelled in the UI thread, so we'll accept them unless we're |
| 337 // complete. | 352 // complete. |
| 338 void DownloadItem::Update(int64 bytes_so_far) { | 353 void DownloadItem::Update(int64 bytes_so_far, const std::string& partial_hash) { |
| 339 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 354 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 340 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 355 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 341 | 356 |
| 342 if (!IsInProgress()) { | 357 if (!IsInProgress()) { |
| 343 NOTREACHED(); | 358 NOTREACHED(); |
| 344 return; | 359 return; |
| 345 } | 360 } |
| 346 UpdateSize(bytes_so_far); | 361 UpdateSizeAndHash(bytes_so_far, partial_hash); |
| 347 UpdateObservers(); | 362 UpdateObservers(); |
| 348 } | 363 } |
| 349 | 364 |
| 350 // Triggered by a user action. | 365 // Triggered by a user action. |
| 351 void DownloadItem::Cancel(bool user_cancel) { | 366 void DownloadItem::Cancel(bool user_cancel) { |
| 352 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 367 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 353 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 368 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 354 | 369 |
| 355 last_reason_ = user_cancel ? | 370 last_reason_ = user_cancel ? |
| 356 DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : | 371 DOWNLOAD_INTERRUPT_REASON_USER_CANCELED : |
| (...skipping 26 matching lines...) Expand all Loading... |
| 383 auto_opened_ = true; | 398 auto_opened_ = true; |
| 384 Completed(); | 399 Completed(); |
| 385 } | 400 } |
| 386 | 401 |
| 387 void DownloadItem::OnAllDataSaved(int64 size, const std::string& final_hash) { | 402 void DownloadItem::OnAllDataSaved(int64 size, const std::string& final_hash) { |
| 388 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 403 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 389 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 404 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 390 | 405 |
| 391 DCHECK(!all_data_saved_); | 406 DCHECK(!all_data_saved_); |
| 392 all_data_saved_ = true; | 407 all_data_saved_ = true; |
| 393 UpdateSize(size); | 408 UpdateSizeAndHash(size, final_hash); |
| 394 hash_ = final_hash; | |
| 395 } | 409 } |
| 396 | 410 |
| 397 void DownloadItem::OnDownloadedFileRemoved() { | 411 void DownloadItem::OnDownloadedFileRemoved() { |
| 398 file_externally_removed_ = true; | 412 file_externally_removed_ = true; |
| 399 UpdateObservers(); | 413 UpdateObservers(); |
| 400 } | 414 } |
| 401 | 415 |
| 402 void DownloadItem::Completed() { | 416 void DownloadItem::Completed() { |
| 403 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 417 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 404 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 418 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 } | 460 } |
| 447 | 461 |
| 448 void DownloadItem::UpdateTarget() { | 462 void DownloadItem::UpdateTarget() { |
| 449 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 463 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 450 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 464 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 451 | 465 |
| 452 if (state_info_.target_name.value().empty()) | 466 if (state_info_.target_name.value().empty()) |
| 453 state_info_.target_name = full_path_.BaseName(); | 467 state_info_.target_name = full_path_.BaseName(); |
| 454 } | 468 } |
| 455 | 469 |
| 456 void DownloadItem::Interrupted(int64 size, InterruptReason reason) { | 470 void DownloadItem::Interrupted(int64 size, |
| 471 const std::string partial_hash, |
| 472 InterruptReason reason) { |
| 457 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 473 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 458 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 474 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 459 | 475 |
| 460 if (!IsInProgress()) | 476 if (!IsInProgress()) |
| 461 return; | 477 return; |
| 462 | 478 |
| 463 last_reason_ = reason; | 479 last_reason_ = reason; |
| 464 UpdateSize(size); | 480 UpdateSizeAndHash(size, partial_hash); |
| 465 download_stats::RecordDownloadInterrupted(reason, | 481 download_stats::RecordDownloadInterrupted(reason, |
| 466 received_bytes_, | 482 received_bytes_, |
| 467 total_bytes_); | 483 total_bytes_); |
| 468 TransitionTo(INTERRUPTED); | 484 TransitionTo(INTERRUPTED); |
| 469 } | 485 } |
| 470 | 486 |
| 471 void DownloadItem::Delete(DeleteReason reason) { | 487 void DownloadItem::Delete(DeleteReason reason) { |
| 472 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 488 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 473 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 489 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 474 | 490 |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 DownloadPersistentStoreInfo DownloadItem::GetPersistentStoreInfo() const { | 689 DownloadPersistentStoreInfo DownloadItem::GetPersistentStoreInfo() const { |
| 674 return DownloadPersistentStoreInfo(full_path(), | 690 return DownloadPersistentStoreInfo(full_path(), |
| 675 GetURL(), | 691 GetURL(), |
| 676 referrer_url(), | 692 referrer_url(), |
| 677 start_time(), | 693 start_time(), |
| 678 end_time(), | 694 end_time(), |
| 679 received_bytes(), | 695 received_bytes(), |
| 680 total_bytes(), | 696 total_bytes(), |
| 681 state(), | 697 state(), |
| 682 db_handle(), | 698 db_handle(), |
| 683 opened()); | 699 opened(), |
| 700 download_id_.local(), |
| 701 hash_, |
| 702 last_modified_time_, |
| 703 etag_, |
| 704 last_reason_); |
| 684 } | 705 } |
| 685 | 706 |
| 686 TabContents* DownloadItem::GetTabContents() const { | 707 TabContents* DownloadItem::GetTabContents() const { |
| 687 if (request_handle_.get()) | 708 if (request_handle_.get()) |
| 688 return request_handle_->GetTabContents(); | 709 return request_handle_->GetTabContents(); |
| 689 return NULL; | 710 return NULL; |
| 690 } | 711 } |
| 691 | 712 |
| 692 FilePath DownloadItem::GetTargetFilePath() const { | 713 FilePath DownloadItem::GetTargetFilePath() const { |
| 693 return full_path_.DirName().Append(state_info_.target_name); | 714 return full_path_.DirName().Append(state_info_.target_name); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 714 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 735 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 715 base::Bind(&DownloadFileManager::CancelDownload, | 736 base::Bind(&DownloadFileManager::CancelDownload, |
| 716 file_manager, global_id())); | 737 file_manager, global_id())); |
| 717 } | 738 } |
| 718 | 739 |
| 719 void DownloadItem::Init(bool active) { | 740 void DownloadItem::Init(bool active) { |
| 720 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. | 741 // TODO(rdsmith): Change to DCHECK after http://crbug.com/85408 resolved. |
| 721 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 742 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 722 | 743 |
| 723 UpdateTarget(); | 744 UpdateTarget(); |
| 724 if (active) { | 745 if (active) |
| 725 download_stats::RecordDownloadCount(download_stats::START_COUNT); | 746 download_stats::RecordDownloadCount(download_stats::START_COUNT); |
| 726 } | |
| 727 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); | 747 VLOG(20) << __FUNCTION__ << "() " << DebugString(true); |
| 728 } | 748 } |
| 729 | 749 |
| 730 // TODO(ahendrickson) -- Move |INTERRUPTED| from |IsCancelled()| to | 750 // TODO(ahendrickson) -- Move |INTERRUPTED| from |IsCancelled()| to |
| 731 // |IsPartialDownload()|, when resuming interrupted downloads is implemented. | 751 // |IsPartialDownload()|, when resuming interrupted downloads is implemented. |
| 732 bool DownloadItem::IsPartialDownload() const { | 752 bool DownloadItem::IsPartialDownload() const { |
| 733 return (state_ == IN_PROGRESS); | 753 return (state_ == IN_PROGRESS); |
| 734 } | 754 } |
| 735 | 755 |
| 736 bool DownloadItem::IsInProgress() const { | 756 bool DownloadItem::IsInProgress() const { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 } | 797 } |
| 778 | 798 |
| 779 if (verbose) { | 799 if (verbose) { |
| 780 description += base::StringPrintf( | 800 description += base::StringPrintf( |
| 781 " db_handle = %" PRId64 | 801 " db_handle = %" PRId64 |
| 782 " total_bytes = %" PRId64 | 802 " total_bytes = %" PRId64 |
| 783 " received_bytes = %" PRId64 | 803 " received_bytes = %" PRId64 |
| 784 " is_paused = %c" | 804 " is_paused = %c" |
| 785 " is_otr = %c" | 805 " is_otr = %c" |
| 786 " safety_state = %s" | 806 " safety_state = %s" |
| 807 " last_modified = '%s'" |
| 808 " etag = '%s'" |
| 787 " url_chain = \n\t\"%s\"\n\t" | 809 " url_chain = \n\t\"%s\"\n\t" |
| 788 " target_name = \"%" PRFilePath "\"" | 810 " target_name = \"%" PRFilePath "\"" |
| 789 " full_path = \"%" PRFilePath "\"", | 811 " full_path = \"%" PRFilePath "\"", |
| 790 db_handle(), | 812 db_handle(), |
| 791 total_bytes(), | 813 total_bytes(), |
| 792 received_bytes(), | 814 received_bytes(), |
| 793 is_paused() ? 'T' : 'F', | 815 is_paused() ? 'T' : 'F', |
| 794 is_otr() ? 'T' : 'F', | 816 is_otr() ? 'T' : 'F', |
| 795 DebugSafetyStateString(safety_state()), | 817 DebugSafetyStateString(safety_state()), |
| 818 last_modified_time_.c_str(), |
| 819 etag_.c_str(), |
| 796 url_list.c_str(), | 820 url_list.c_str(), |
| 797 state_info_.target_name.value().c_str(), | 821 state_info_.target_name.value().c_str(), |
| 798 full_path().value().c_str()); | 822 full_path().value().c_str()); |
| 799 } else { | 823 } else { |
| 800 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); | 824 description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); |
| 801 } | 825 } |
| 802 | 826 |
| 803 description += " }"; | 827 description += " }"; |
| 804 | 828 |
| 805 return description; | 829 return description; |
| 806 } | 830 } |
| OLD | NEW |