persistent_download.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "weblayer/browser/persistent_download.h"
  5. #include "base/bind.h"
  6. #include "base/files/file_path.h"
  7. #include "base/memory/ptr_util.h"
  8. #include "base/threading/sequenced_task_runner_handle.h"
  9. #include "components/download/public/common/download_item.h"
  10. namespace weblayer {
  11. namespace {
  12. const char kPersistentDownloadKeyName[] = "weblayer_download_impl";
  13. }
  14. PersistentDownload::~PersistentDownload() = default;
  15. void PersistentDownload::Create(download::DownloadItem* item) {
  16. item->SetUserData(kPersistentDownloadKeyName,
  17. base::WrapUnique(new PersistentDownload(item)));
  18. }
  19. PersistentDownload* PersistentDownload::Get(download::DownloadItem* item) {
  20. return static_cast<PersistentDownload*>(
  21. item->GetUserData(kPersistentDownloadKeyName));
  22. }
  23. DownloadState PersistentDownload::GetState() {
  24. if (item_->GetState() == download::DownloadItem::COMPLETE)
  25. return DownloadState::kComplete;
  26. if (cancel_pending_ || item_->GetState() == download::DownloadItem::CANCELLED)
  27. return DownloadState::kCancelled;
  28. if (pause_pending_ || (item_->IsPaused() && !resume_pending_))
  29. return DownloadState::kPaused;
  30. if (resume_pending_ ||
  31. item_->GetState() == download::DownloadItem::IN_PROGRESS) {
  32. return DownloadState::kInProgress;
  33. }
  34. return DownloadState::kFailed;
  35. }
  36. int64_t PersistentDownload::GetTotalBytes() {
  37. return item_->GetTotalBytes();
  38. }
  39. int64_t PersistentDownload::GetReceivedBytes() {
  40. return item_->GetReceivedBytes();
  41. }
  42. void PersistentDownload::Pause() {
  43. // The Pause/Resume/Cancel methods need to be called in a PostTask because we
  44. // may be in a callback from the download subsystem and it doesn't handle
  45. // nested calls.
  46. resume_pending_ = false;
  47. pause_pending_ = true;
  48. base::SequencedTaskRunnerHandle::Get()->PostTask(
  49. FROM_HERE, base::BindOnce(&PersistentDownload::PauseInternal,
  50. weak_ptr_factory_.GetWeakPtr()));
  51. }
  52. void PersistentDownload::Resume() {
  53. pause_pending_ = false;
  54. resume_pending_ = true;
  55. base::SequencedTaskRunnerHandle::Get()->PostTask(
  56. FROM_HERE, base::BindOnce(&PersistentDownload::ResumeInternal,
  57. weak_ptr_factory_.GetWeakPtr()));
  58. }
  59. void PersistentDownload::Cancel() {
  60. cancel_pending_ = true;
  61. base::SequencedTaskRunnerHandle::Get()->PostTask(
  62. FROM_HERE, base::BindOnce(&PersistentDownload::CancelInternal,
  63. weak_ptr_factory_.GetWeakPtr()));
  64. }
  65. base::FilePath PersistentDownload::GetLocation() {
  66. return item_->GetTargetFilePath();
  67. }
  68. std::u16string PersistentDownload::GetFileNameToReportToUser() {
  69. return item_->GetFileNameToReportUser().LossyDisplayName();
  70. }
  71. std::string PersistentDownload::GetMimeType() {
  72. return item_->GetMimeType();
  73. }
  74. DownloadError PersistentDownload::GetError() {
  75. auto reason = item_->GetLastReason();
  76. if (reason == download::DOWNLOAD_INTERRUPT_REASON_NONE)
  77. return DownloadError::kNoError;
  78. if (reason == download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM)
  79. return DownloadError::kSSLError;
  80. if (reason >= download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED &&
  81. reason <=
  82. download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT)
  83. return DownloadError::kServerError;
  84. if (reason >= download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED &&
  85. reason <= download::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST)
  86. return DownloadError::kConnectivityError;
  87. if (reason == download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE)
  88. return DownloadError::kNoSpace;
  89. if (reason >= download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED &&
  90. reason <= download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE)
  91. return DownloadError::kFileError;
  92. if (reason == download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED)
  93. return DownloadError::kCancelled;
  94. return DownloadError::kOtherError;
  95. }
  96. PersistentDownload::PersistentDownload(download::DownloadItem* item)
  97. : item_(item) {}
  98. void PersistentDownload::PauseInternal() {
  99. if (pause_pending_) {
  100. pause_pending_ = false;
  101. item_->Pause();
  102. }
  103. }
  104. int PersistentDownload::GetNotificationId() {
  105. return item_->GetId();
  106. }
  107. bool PersistentDownload::IsTransient() {
  108. return false;
  109. }
  110. GURL PersistentDownload::GetSourceUrl() {
  111. return {};
  112. }
  113. const SkBitmap* PersistentDownload::GetLargeIcon() {
  114. return nullptr;
  115. }
  116. void PersistentDownload::OnFinished(bool activated) {
  117. // For this type of download, activation is handled purely in Java.
  118. }
  119. void PersistentDownload::ResumeInternal() {
  120. if (resume_pending_) {
  121. resume_pending_ = false;
  122. item_->Resume(true);
  123. }
  124. }
  125. void PersistentDownload::CancelInternal() {
  126. cancel_pending_ = false;
  127. item_->Cancel(true);
  128. }
  129. } // namespace weblayer