| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 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/background_fetch/background_fetch_job_controller.h" | 5 #include "content/browser/background_fetch/background_fetch_job_controller.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 | 33 |
| 34 ~Core() final { | 34 ~Core() final { |
| 35 for (const auto& pair : downloads_) | 35 for (const auto& pair : downloads_) |
| 36 pair.first->RemoveObserver(this); | 36 pair.first->RemoveObserver(this); |
| 37 } | 37 } |
| 38 | 38 |
| 39 // Returns a weak pointer that can be used to talk to |this|. | 39 // Returns a weak pointer that can be used to talk to |this|. |
| 40 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } | 40 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } |
| 41 | 41 |
| 42 // Starts fetching the |request| with the download manager. | 42 // Starts fetching the |request| with the download manager. |
| 43 void StartRequest(const BackgroundFetchRequestInfo& request) { | 43 void StartRequest(scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 44 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 44 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 45 DCHECK(request_context_); | 45 DCHECK(request_context_); |
| 46 DCHECK(request); |
| 46 | 47 |
| 47 DownloadManager* download_manager = | 48 DownloadManager* download_manager = |
| 48 BrowserContext::GetDownloadManager(browser_context_); | 49 BrowserContext::GetDownloadManager(browser_context_); |
| 49 DCHECK(download_manager); | 50 DCHECK(download_manager); |
| 50 | 51 |
| 51 std::unique_ptr<DownloadUrlParameters> download_parameters( | 52 std::unique_ptr<DownloadUrlParameters> download_parameters( |
| 52 base::MakeUnique<DownloadUrlParameters>(request.GetURL(), | 53 base::MakeUnique<DownloadUrlParameters>(request->GetURL(), |
| 53 request_context_.get())); | 54 request_context_.get())); |
| 54 | 55 |
| 55 // TODO(peter): The |download_parameters| should be populated with all the | 56 // TODO(peter): The |download_parameters| should be populated with all the |
| 56 // properties set in the |request|'s ServiceWorkerFetchRequest member. | 57 // properties set in the |request|'s ServiceWorkerFetchRequest member. |
| 57 | 58 |
| 58 download_parameters->set_callback(base::Bind( | 59 download_parameters->set_callback(base::Bind(&Core::DidStartRequest, |
| 59 &Core::DidStartRequest, weak_ptr_factory_.GetWeakPtr(), request)); | 60 weak_ptr_factory_.GetWeakPtr(), |
| 61 std::move(request))); |
| 60 | 62 |
| 61 download_manager->DownloadUrl(std::move(download_parameters)); | 63 download_manager->DownloadUrl(std::move(download_parameters)); |
| 62 } | 64 } |
| 63 | 65 |
| 64 // DownloadItem::Observer overrides: | 66 // DownloadItem::Observer overrides: |
| 65 void OnDownloadUpdated(DownloadItem* item) override { | 67 void OnDownloadUpdated(DownloadItem* item) override { |
| 66 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 68 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 67 | 69 |
| 68 auto iter = downloads_.find(item); | 70 auto iter = downloads_.find(item); |
| 69 DCHECK(iter != downloads_.end()); | 71 DCHECK(iter != downloads_.end()); |
| 70 | 72 |
| 71 const BackgroundFetchRequestInfo& request = iter->second; | 73 const scoped_refptr<BackgroundFetchRequestInfo>& request = iter->second; |
| 72 | 74 |
| 73 switch (item->GetState()) { | 75 switch (item->GetState()) { |
| 74 case DownloadItem::DownloadState::COMPLETE: | 76 case DownloadItem::DownloadState::COMPLETE: |
| 75 // TODO(peter): Populate the responses' information in the |request|. | 77 // TODO(peter): Populate the responses' information in the |request|. |
| 76 | 78 |
| 77 item->RemoveObserver(this); | 79 item->RemoveObserver(this); |
| 78 | 80 |
| 79 // Inform the host about |host| having completed. | 81 // Inform the host about |host| having completed. |
| 80 BrowserThread::PostTask( | 82 BrowserThread::PostTask( |
| 81 BrowserThread::IO, FROM_HERE, | 83 BrowserThread::IO, FROM_HERE, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 106 DCHECK_EQ(downloads_.count(item), 1u); | 108 DCHECK_EQ(downloads_.count(item), 1u); |
| 107 downloads_.erase(item); | 109 downloads_.erase(item); |
| 108 | 110 |
| 109 item->RemoveObserver(this); | 111 item->RemoveObserver(this); |
| 110 } | 112 } |
| 111 | 113 |
| 112 private: | 114 private: |
| 113 // Called when the download manager has started the given |request|. The | 115 // Called when the download manager has started the given |request|. The |
| 114 // |download_item| continues to be owned by the download system. The | 116 // |download_item| continues to be owned by the download system. The |
| 115 // |interrupt_reason| will indicate when a request could not be started. | 117 // |interrupt_reason| will indicate when a request could not be started. |
| 116 void DidStartRequest(const BackgroundFetchRequestInfo& request, | 118 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, |
| 117 DownloadItem* download_item, | 119 DownloadItem* download_item, |
| 118 DownloadInterruptReason interrupt_reason) { | 120 DownloadInterruptReason interrupt_reason) { |
| 119 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 121 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 120 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); | 122 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); |
| 121 DCHECK(download_item); | 123 DCHECK(download_item); |
| 122 | 124 |
| 123 // TODO(peter): The above two DCHECKs are assumptions our implementation | 125 // TODO(peter): The above two DCHECKs are assumptions our implementation |
| 124 // currently makes, but are not fit for production. We need to handle such | 126 // currently makes, but are not fit for production. We need to handle such |
| 125 // failures gracefully. | 127 // failures gracefully. |
| 126 | 128 |
| 127 // Register for updates on the download's progress. | 129 // Register for updates on the download's progress. |
| 128 download_item->AddObserver(this); | 130 download_item->AddObserver(this); |
| 129 | 131 |
| 130 // Inform the host about the |request| having started. | 132 // Inform the host about the |request| having started. |
| 131 BrowserThread::PostTask( | 133 BrowserThread::PostTask( |
| 132 BrowserThread::IO, FROM_HERE, | 134 BrowserThread::IO, FROM_HERE, |
| 133 base::Bind(&BackgroundFetchJobController::DidStartRequest, io_parent_, | 135 base::Bind(&BackgroundFetchJobController::DidStartRequest, io_parent_, |
| 134 request, download_item->GetGuid())); | 136 request, download_item->GetGuid())); |
| 135 | 137 |
| 136 // Associate the |download_item| with the |request| so that we can retrieve | 138 // Associate the |download_item| with the |request| so that we can retrieve |
| 137 // it's information when further updates happen. | 139 // it's information when further updates happen. |
| 138 downloads_.insert(std::make_pair(download_item, request)); | 140 downloads_.insert(std::make_pair(download_item, std::move(request))); |
| 139 } | 141 } |
| 140 | 142 |
| 141 // Weak reference to the BackgroundFetchJobController instance that owns us. | 143 // Weak reference to the BackgroundFetchJobController instance that owns us. |
| 142 base::WeakPtr<BackgroundFetchJobController> io_parent_; | 144 base::WeakPtr<BackgroundFetchJobController> io_parent_; |
| 143 | 145 |
| 144 // The BrowserContext that owns the JobController, and thereby us. | 146 // The BrowserContext that owns the JobController, and thereby us. |
| 145 BrowserContext* browser_context_; | 147 BrowserContext* browser_context_; |
| 146 | 148 |
| 147 // The URL request context to use when issuing the requests. | 149 // The URL request context to use when issuing the requests. |
| 148 scoped_refptr<net::URLRequestContextGetter> request_context_; | 150 scoped_refptr<net::URLRequestContextGetter> request_context_; |
| 149 | 151 |
| 150 // Map from DownloadItem* to the request info for the in-progress downloads. | 152 // Map from DownloadItem* to the request info for the in-progress downloads. |
| 151 std::unordered_map<DownloadItem*, BackgroundFetchRequestInfo> downloads_; | 153 std::unordered_map<DownloadItem*, scoped_refptr<BackgroundFetchRequestInfo>> |
| 154 downloads_; |
| 152 | 155 |
| 153 base::WeakPtrFactory<Core> weak_ptr_factory_; | 156 base::WeakPtrFactory<Core> weak_ptr_factory_; |
| 154 | 157 |
| 155 DISALLOW_COPY_AND_ASSIGN(Core); | 158 DISALLOW_COPY_AND_ASSIGN(Core); |
| 156 }; | 159 }; |
| 157 | 160 |
| 158 BackgroundFetchJobController::BackgroundFetchJobController( | 161 BackgroundFetchJobController::BackgroundFetchJobController( |
| 159 const BackgroundFetchRegistrationId& registration_id, | 162 const BackgroundFetchRegistrationId& registration_id, |
| 160 const BackgroundFetchOptions& options, | 163 const BackgroundFetchOptions& options, |
| 161 BackgroundFetchDataManager* data_manager, | 164 BackgroundFetchDataManager* data_manager, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 174 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), browser_context, | 177 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), browser_context, |
| 175 std::move(request_context))); | 178 std::move(request_context))); |
| 176 | 179 |
| 177 // Get a WeakPtr over which we can talk to the |ui_core_|. | 180 // Get a WeakPtr over which we can talk to the |ui_core_|. |
| 178 ui_core_ptr_ = ui_core_->GetWeakPtr(); | 181 ui_core_ptr_ = ui_core_->GetWeakPtr(); |
| 179 } | 182 } |
| 180 | 183 |
| 181 BackgroundFetchJobController::~BackgroundFetchJobController() = default; | 184 BackgroundFetchJobController::~BackgroundFetchJobController() = default; |
| 182 | 185 |
| 183 void BackgroundFetchJobController::Start( | 186 void BackgroundFetchJobController::Start( |
| 184 std::vector<BackgroundFetchRequestInfo> initial_requests) { | 187 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { |
| 185 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 186 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); | 189 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); |
| 187 DCHECK_EQ(state_, State::INITIALIZED); | 190 DCHECK_EQ(state_, State::INITIALIZED); |
| 188 | 191 |
| 189 state_ = State::FETCHING; | 192 state_ = State::FETCHING; |
| 190 | 193 |
| 191 for (const BackgroundFetchRequestInfo& request : initial_requests) | 194 for (const auto& request : initial_requests) |
| 192 StartRequest(request); | 195 StartRequest(request); |
| 193 } | 196 } |
| 194 | 197 |
| 195 void BackgroundFetchJobController::StartRequest( | 198 void BackgroundFetchJobController::StartRequest( |
| 196 const BackgroundFetchRequestInfo& request) { | 199 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 197 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 200 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 198 DCHECK_EQ(state_, State::FETCHING); | 201 DCHECK_EQ(state_, State::FETCHING); |
| 199 BrowserThread::PostTask( | 202 BrowserThread::PostTask( |
| 200 BrowserThread::UI, FROM_HERE, | 203 BrowserThread::UI, FROM_HERE, |
| 201 base::Bind(&Core::StartRequest, ui_core_ptr_, request)); | 204 base::Bind(&Core::StartRequest, ui_core_ptr_, std::move(request))); |
| 202 } | 205 } |
| 203 | 206 |
| 204 void BackgroundFetchJobController::DidStartRequest( | 207 void BackgroundFetchJobController::DidStartRequest( |
| 205 const BackgroundFetchRequestInfo& request, | 208 scoped_refptr<BackgroundFetchRequestInfo> request, |
| 206 const std::string& download_guid) { | 209 const std::string& download_guid) { |
| 207 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 210 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 208 data_manager_->MarkRequestAsStarted(registration_id_, request, download_guid); | 211 data_manager_->MarkRequestAsStarted(registration_id_, request.get(), |
| 212 download_guid); |
| 209 } | 213 } |
| 210 | 214 |
| 211 void BackgroundFetchJobController::DidCompleteRequest( | 215 void BackgroundFetchJobController::DidCompleteRequest( |
| 212 const BackgroundFetchRequestInfo& request) { | 216 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 213 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 217 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 214 | 218 |
| 215 // The DataManager must acknowledge that it stored the data and that there are | 219 // The DataManager must acknowledge that it stored the data and that there are |
| 216 // no more pending requests to avoid marking this job as completed too early. | 220 // no more pending requests to avoid marking this job as completed too early. |
| 217 pending_completed_file_acknowledgements_++; | 221 pending_completed_file_acknowledgements_++; |
| 218 | 222 |
| 219 data_manager_->MarkRequestAsCompleteAndGetNextRequest( | 223 data_manager_->MarkRequestAsCompleteAndGetNextRequest( |
| 220 registration_id_, request, | 224 registration_id_, request.get(), |
| 221 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, | 225 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, |
| 222 weak_ptr_factory_.GetWeakPtr())); | 226 weak_ptr_factory_.GetWeakPtr())); |
| 223 } | 227 } |
| 224 | 228 |
| 225 void BackgroundFetchJobController::DidGetNextRequest( | 229 void BackgroundFetchJobController::DidGetNextRequest( |
| 226 const base::Optional<BackgroundFetchRequestInfo>& request) { | 230 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 227 DCHECK_LE(pending_completed_file_acknowledgements_, 1); | 231 DCHECK_LE(pending_completed_file_acknowledgements_, 1); |
| 228 pending_completed_file_acknowledgements_--; | 232 pending_completed_file_acknowledgements_--; |
| 229 | 233 |
| 230 // If a |request| has been given, start downloading the file and bail. | 234 // If a |request| has been given, start downloading the file and bail. |
| 231 if (request) { | 235 if (request) { |
| 232 StartRequest(request.value()); | 236 StartRequest(std::move(request)); |
| 233 return; | 237 return; |
| 234 } | 238 } |
| 235 | 239 |
| 236 // If there are outstanding completed file acknowlegements, bail as well. | 240 // If there are outstanding completed file acknowlegements, bail as well. |
| 237 if (pending_completed_file_acknowledgements_ > 0) | 241 if (pending_completed_file_acknowledgements_ > 0) |
| 238 return; | 242 return; |
| 239 | 243 |
| 240 state_ = State::COMPLETED; | 244 state_ = State::COMPLETED; |
| 241 | 245 |
| 242 // Otherwise the job this controller is responsible for has completed. | 246 // Otherwise the job this controller is responsible for has completed. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 254 | 258 |
| 255 // TODO(harkness): Abort all in-progress downloads. | 259 // TODO(harkness): Abort all in-progress downloads. |
| 256 | 260 |
| 257 state_ = State::ABORTED; | 261 state_ = State::ABORTED; |
| 258 | 262 |
| 259 // Inform the owner of the controller about the job having completed. | 263 // Inform the owner of the controller about the job having completed. |
| 260 std::move(completed_callback_).Run(this); | 264 std::move(completed_callback_).Run(this); |
| 261 } | 265 } |
| 262 | 266 |
| 263 } // namespace content | 267 } // namespace content |
| OLD | NEW |