OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 |
| 5 #include "components/download/content/download_driver_impl.h" |
| 6 |
| 7 #include "components/download/internal/driver_entry.h" |
| 8 #include "content/public/browser/download_interrupt_reasons.h" |
| 9 #include "content/public/browser/download_url_parameters.h" |
| 10 #include "content/public/browser/storage_partition.h" |
| 11 #include "net/http/http_response_headers.h" |
| 12 |
| 13 namespace download { |
| 14 |
| 15 namespace { |
| 16 |
| 17 // Converts a content::DownloadItem::DownloadState to DriverEntry::State. |
| 18 DriverEntry::State ToDriverEntryState( |
| 19 content::DownloadItem::DownloadState state) { |
| 20 switch (state) { |
| 21 case content::DownloadItem::IN_PROGRESS: |
| 22 return DriverEntry::State::IN_PROGRESS; |
| 23 case content::DownloadItem::COMPLETE: |
| 24 return DriverEntry::State::COMPLETE; |
| 25 case content::DownloadItem::CANCELLED: |
| 26 return DriverEntry::State::CANCELLED; |
| 27 case content::DownloadItem::INTERRUPTED: |
| 28 return DriverEntry::State::INTERRUPTED; |
| 29 case content::DownloadItem::MAX_DOWNLOAD_STATE: |
| 30 return DriverEntry::State::UNKNOWN; |
| 31 default: |
| 32 NOTREACHED(); |
| 33 return DriverEntry::State::UNKNOWN; |
| 34 } |
| 35 } |
| 36 |
| 37 } // namespace |
| 38 |
| 39 // static |
| 40 DriverEntry DownloadDriverImpl::CreateDriverEntry( |
| 41 const content::DownloadItem* item) { |
| 42 DCHECK(item); |
| 43 DriverEntry entry; |
| 44 entry.guid = item->GetGuid(); |
| 45 entry.state = ToDriverEntryState(item->GetState()); |
| 46 entry.paused = item->IsPaused(); |
| 47 entry.bytes_downloaded = item->GetReceivedBytes(); |
| 48 entry.expected_total_size = item->GetTotalBytes(); |
| 49 entry.response_headers = item->GetResponseHeaders(); |
| 50 return entry; |
| 51 } |
| 52 |
| 53 DownloadDriverImpl::DownloadDriverImpl(content::DownloadManager* manager, |
| 54 const base::FilePath& dir) |
| 55 : download_manager_(manager), file_dir_(dir), client_(nullptr) { |
| 56 DCHECK(download_manager_); |
| 57 } |
| 58 |
| 59 DownloadDriverImpl::~DownloadDriverImpl() { |
| 60 if (download_manager_) |
| 61 download_manager_->RemoveObserver(this); |
| 62 } |
| 63 |
| 64 void DownloadDriverImpl::Initialize(DownloadDriver::Client* client) { |
| 65 DCHECK(!client_); |
| 66 client_ = client; |
| 67 DCHECK(client_); |
| 68 |
| 69 // |download_manager_| may be shut down. Informs the client. |
| 70 if (!download_manager_) { |
| 71 client_->OnDriverReady(false); |
| 72 return; |
| 73 } |
| 74 |
| 75 download_manager_->AddObserver(this); |
| 76 if (download_manager_->IsManagerInitialized()) |
| 77 client_->OnDriverReady(true); |
| 78 } |
| 79 |
| 80 bool DownloadDriverImpl::IsReady() const { |
| 81 return client_ && download_manager_; |
| 82 } |
| 83 |
| 84 void DownloadDriverImpl::Start(const DownloadParams& params) { |
| 85 DCHECK(!params.request_params.url.is_empty()); |
| 86 DCHECK(!params.guid.empty()); |
| 87 if (!download_manager_) |
| 88 return; |
| 89 |
| 90 content::StoragePartition* storage_partition = |
| 91 content::BrowserContext::GetStoragePartitionForSite( |
| 92 download_manager_->GetBrowserContext(), params.request_params.url); |
| 93 DCHECK(storage_partition); |
| 94 |
| 95 std::unique_ptr<content::DownloadUrlParameters> download_url_params( |
| 96 new content::DownloadUrlParameters( |
| 97 params.request_params.url, |
| 98 storage_partition->GetURLRequestContext())); |
| 99 |
| 100 // TODO(xingliu): Handle the request headers from |params|, need to tweak |
| 101 // download network stack. |
| 102 // Make content::DownloadManager handle potential guid collision and return |
| 103 // an error to fail the download cleanly. |
| 104 download_url_params->set_guid(params.guid); |
| 105 download_url_params->set_transient(true); |
| 106 download_url_params->set_method(params.request_params.method); |
| 107 download_url_params->set_file_path(file_dir_.AppendASCII(params.guid)); |
| 108 |
| 109 download_manager_->DownloadUrl(std::move(download_url_params)); |
| 110 } |
| 111 |
| 112 void DownloadDriverImpl::Cancel(const std::string& guid) { |
| 113 if (!download_manager_) |
| 114 return; |
| 115 content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid); |
| 116 // Cancels the download and removes the persisted records in content layer. |
| 117 if (item) { |
| 118 item->RemoveObserver(this); |
| 119 item->Remove(); |
| 120 } |
| 121 } |
| 122 |
| 123 void DownloadDriverImpl::Pause(const std::string& guid) { |
| 124 if (!download_manager_) |
| 125 return; |
| 126 content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid); |
| 127 if (item) |
| 128 item->Pause(); |
| 129 } |
| 130 |
| 131 void DownloadDriverImpl::Resume(const std::string& guid) { |
| 132 if (!download_manager_) |
| 133 return; |
| 134 content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid); |
| 135 if (item) |
| 136 item->Resume(); |
| 137 } |
| 138 |
| 139 base::Optional<DriverEntry> DownloadDriverImpl::Find(const std::string& guid) { |
| 140 if (!download_manager_) |
| 141 return base::nullopt; |
| 142 content::DownloadItem* item = download_manager_->GetDownloadByGuid(guid); |
| 143 if (item) |
| 144 return CreateDriverEntry(item); |
| 145 return base::nullopt; |
| 146 } |
| 147 |
| 148 void DownloadDriverImpl::OnDownloadUpdated(content::DownloadItem* item) { |
| 149 DCHECK(client_); |
| 150 |
| 151 using DownloadState = content::DownloadItem::DownloadState; |
| 152 DownloadState state = item->GetState(); |
| 153 content::DownloadInterruptReason reason = item->GetLastReason(); |
| 154 DriverEntry entry = CreateDriverEntry(item); |
| 155 |
| 156 if (state == DownloadState::COMPLETE) { |
| 157 client_->OnDownloadSucceeded(entry, item->GetTargetFilePath()); |
| 158 item->RemoveObserver(this); |
| 159 } else if (state == DownloadState::IN_PROGRESS) { |
| 160 client_->OnDownloadUpdated(entry); |
| 161 } else if (reason != |
| 162 content::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 163 client_->OnDownloadFailed(entry, static_cast<int>(reason)); |
| 164 item->RemoveObserver(this); |
| 165 } |
| 166 } |
| 167 |
| 168 void DownloadDriverImpl::OnDownloadCreated(content::DownloadManager* manager, |
| 169 content::DownloadItem* item) { |
| 170 // Listens to all downloads. |
| 171 item->AddObserver(this); |
| 172 DCHECK(client_); |
| 173 DriverEntry entry = CreateDriverEntry(item); |
| 174 client_->OnDownloadCreated(entry); |
| 175 } |
| 176 |
| 177 void DownloadDriverImpl::OnManagerInitialized() { |
| 178 DCHECK(client_); |
| 179 DCHECK(download_manager_); |
| 180 client_->OnDriverReady(true); |
| 181 } |
| 182 |
| 183 void DownloadDriverImpl::ManagerGoingDown(content::DownloadManager* manager) { |
| 184 DCHECK_EQ(download_manager_, manager); |
| 185 download_manager_ = nullptr; |
| 186 } |
| 187 |
| 188 } // namespace download |
OLD | NEW |