| 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 30 matching lines...) Expand all Loading... |
| 41 class BackgroundFetchJobController::Core : public DownloadItem::Observer { | 41 class BackgroundFetchJobController::Core : public DownloadItem::Observer { |
| 42 public: | 42 public: |
| 43 Core(const base::WeakPtr<BackgroundFetchJobController>& io_parent, | 43 Core(const base::WeakPtr<BackgroundFetchJobController>& io_parent, |
| 44 const BackgroundFetchRegistrationId& registration_id, | 44 const BackgroundFetchRegistrationId& registration_id, |
| 45 BrowserContext* browser_context, | 45 BrowserContext* browser_context, |
| 46 scoped_refptr<net::URLRequestContextGetter> request_context) | 46 scoped_refptr<net::URLRequestContextGetter> request_context) |
| 47 : io_parent_(io_parent), | 47 : io_parent_(io_parent), |
| 48 registration_id_(registration_id), | 48 registration_id_(registration_id), |
| 49 browser_context_(browser_context), | 49 browser_context_(browser_context), |
| 50 request_context_(std::move(request_context)), | 50 request_context_(std::move(request_context)), |
| 51 weak_ptr_factory_(this) {} | 51 weak_ptr_factory_(this) { |
| 52 // Although the Core lives only on the UI thread, it is constructed on IO. |
| 53 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 54 } |
| 52 | 55 |
| 53 ~Core() final { | 56 ~Core() final { |
| 57 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 54 for (const auto& pair : downloads_) | 58 for (const auto& pair : downloads_) |
| 55 pair.first->RemoveObserver(this); | 59 pair.first->RemoveObserver(this); |
| 56 } | 60 } |
| 57 | 61 |
| 58 // Returns a weak pointer that can be used to talk to |this|. | 62 // Returns a weak pointer that can be used to talk to |this|. Must only be |
| 59 base::WeakPtr<Core> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } | 63 // called on the UI thread, unless the Core is guaranteed not to be destroyed |
| 64 // in parallel with this call. |
| 65 base::WeakPtr<Core> GetWeakPtrOnUI() { |
| 66 return weak_ptr_factory_.GetWeakPtr(); |
| 67 } |
| 60 | 68 |
| 61 // Starts fetching the |request| with the download manager. | 69 // Starts fetching the |request| with the download manager. |
| 62 void StartRequest( | 70 void StartRequest( |
| 63 scoped_refptr<BackgroundFetchRequestInfo> request, | 71 scoped_refptr<BackgroundFetchRequestInfo> request, |
| 64 const net::NetworkTrafficAnnotationTag& traffic_annotation) { | 72 const net::NetworkTrafficAnnotationTag& traffic_annotation) { |
| 65 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 73 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 66 DCHECK(request_context_); | 74 DCHECK(request_context_); |
| 67 DCHECK(request); | 75 DCHECK(request); |
| 68 | 76 |
| 69 DownloadManager* download_manager = | 77 DownloadManager* download_manager = |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 void OnDownloadUpdated(DownloadItem* download_item) override { | 125 void OnDownloadUpdated(DownloadItem* download_item) override { |
| 118 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 126 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 119 | 127 |
| 120 auto iter = downloads_.find(download_item); | 128 auto iter = downloads_.find(download_item); |
| 121 DCHECK(iter != downloads_.end()); | 129 DCHECK(iter != downloads_.end()); |
| 122 | 130 |
| 123 scoped_refptr<BackgroundFetchRequestInfo> request = iter->second; | 131 scoped_refptr<BackgroundFetchRequestInfo> request = iter->second; |
| 124 | 132 |
| 125 switch (download_item->GetState()) { | 133 switch (download_item->GetState()) { |
| 126 case DownloadItem::DownloadState::COMPLETE: | 134 case DownloadItem::DownloadState::COMPLETE: |
| 127 request->PopulateResponseFromDownloadItem(download_item); | 135 request->PopulateResponseFromDownloadItemOnUI(download_item); |
| 136 BrowserThread::PostTask( |
| 137 BrowserThread::IO, FROM_HERE, |
| 138 base::Bind(&BackgroundFetchRequestInfo::SetResponseDataPopulated, |
| 139 request)); |
| 128 download_item->RemoveObserver(this); | 140 download_item->RemoveObserver(this); |
| 129 | 141 |
| 130 // Inform the host about |host| having completed. | 142 // Inform the host about |host| having completed. |
| 131 BrowserThread::PostTask( | 143 BrowserThread::PostTask( |
| 132 BrowserThread::IO, FROM_HERE, | 144 BrowserThread::IO, FROM_HERE, |
| 133 base::Bind(&BackgroundFetchJobController::DidCompleteRequest, | 145 base::Bind(&BackgroundFetchJobController::DidCompleteRequest, |
| 134 io_parent_, std::move(request))); | 146 io_parent_, std::move(request))); |
| 135 | 147 |
| 136 // Clear the local state for the |request|, it no longer is our concern. | 148 // Clear the local state for the |request|, it no longer is our concern. |
| 137 downloads_.erase(iter); | 149 downloads_.erase(iter); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 164 // Called when the download manager has started the given |request|. The | 176 // Called when the download manager has started the given |request|. The |
| 165 // |download_item| continues to be owned by the download system. The | 177 // |download_item| continues to be owned by the download system. The |
| 166 // |interrupt_reason| will indicate when a request could not be started. | 178 // |interrupt_reason| will indicate when a request could not be started. |
| 167 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, | 179 void DidStartRequest(scoped_refptr<BackgroundFetchRequestInfo> request, |
| 168 DownloadItem* download_item, | 180 DownloadItem* download_item, |
| 169 DownloadInterruptReason interrupt_reason) { | 181 DownloadInterruptReason interrupt_reason) { |
| 170 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 182 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 171 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); | 183 DCHECK_EQ(interrupt_reason, DOWNLOAD_INTERRUPT_REASON_NONE); |
| 172 DCHECK(download_item); | 184 DCHECK(download_item); |
| 173 | 185 |
| 174 request->PopulateDownloadState(download_item, interrupt_reason); | 186 request->PopulateDownloadStateOnUI(download_item, interrupt_reason); |
| 187 BrowserThread::PostTask( |
| 188 BrowserThread::IO, FROM_HERE, |
| 189 base::Bind(&BackgroundFetchRequestInfo::SetDownloadStatePopulated, |
| 190 request)); |
| 175 | 191 |
| 176 // TODO(peter): The above two DCHECKs are assumptions our implementation | 192 // TODO(peter): The above two DCHECKs are assumptions our implementation |
| 177 // currently makes, but are not fit for production. We need to handle such | 193 // currently makes, but are not fit for production. We need to handle such |
| 178 // failures gracefully. | 194 // failures gracefully. |
| 179 | 195 |
| 180 // Register for updates on the download's progress. | 196 // Register for updates on the download's progress. |
| 181 download_item->AddObserver(this); | 197 download_item->AddObserver(this); |
| 182 | 198 |
| 183 // Inform the host about the |request| having started. | 199 // Inform the host about the |request| having started. |
| 184 BrowserThread::PostTask( | 200 BrowserThread::PostTask( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 completed_callback_(std::move(completed_callback)), | 242 completed_callback_(std::move(completed_callback)), |
| 227 traffic_annotation_(traffic_annotation), | 243 traffic_annotation_(traffic_annotation), |
| 228 weak_ptr_factory_(this) { | 244 weak_ptr_factory_(this) { |
| 229 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 245 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 230 | 246 |
| 231 // Create the core, containing the internal functionality that will have to | 247 // Create the core, containing the internal functionality that will have to |
| 232 // be run on the UI thread. It will respond to this class with a weak pointer. | 248 // be run on the UI thread. It will respond to this class with a weak pointer. |
| 233 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), registration_id, | 249 ui_core_.reset(new Core(weak_ptr_factory_.GetWeakPtr(), registration_id, |
| 234 browser_context, std::move(request_context))); | 250 browser_context, std::move(request_context))); |
| 235 | 251 |
| 236 // Get a WeakPtr over which we can talk to the |ui_core_|. | 252 // Get a WeakPtr over which we can talk to the |ui_core_|. Normally it would |
| 237 ui_core_ptr_ = ui_core_->GetWeakPtr(); | 253 // be unsafe to obtain a weak pointer on the IO thread from a factory that |
| 254 // lives on the UI thread, but it's ok in this constructor since the Core |
| 255 // can't be destroyed before this constructor finishes. |
| 256 ui_core_ptr_ = ui_core_->GetWeakPtrOnUI(); |
| 238 } | 257 } |
| 239 | 258 |
| 240 BackgroundFetchJobController::~BackgroundFetchJobController() = default; | 259 BackgroundFetchJobController::~BackgroundFetchJobController() { |
| 260 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 261 }; |
| 241 | 262 |
| 242 void BackgroundFetchJobController::Start( | 263 void BackgroundFetchJobController::Start( |
| 243 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { | 264 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { |
| 244 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 245 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); | 266 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); |
| 246 DCHECK_EQ(state_, State::INITIALIZED); | 267 DCHECK_EQ(state_, State::INITIALIZED); |
| 247 | 268 |
| 248 state_ = State::FETCHING; | 269 state_ = State::FETCHING; |
| 249 | 270 |
| 250 for (const auto& request : initial_requests) | 271 for (const auto& request : initial_requests) |
| (...skipping 26 matching lines...) Expand all Loading... |
| 277 pending_completed_file_acknowledgements_++; | 298 pending_completed_file_acknowledgements_++; |
| 278 | 299 |
| 279 data_manager_->MarkRequestAsCompleteAndGetNextRequest( | 300 data_manager_->MarkRequestAsCompleteAndGetNextRequest( |
| 280 registration_id_, request.get(), | 301 registration_id_, request.get(), |
| 281 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, | 302 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, |
| 282 weak_ptr_factory_.GetWeakPtr())); | 303 weak_ptr_factory_.GetWeakPtr())); |
| 283 } | 304 } |
| 284 | 305 |
| 285 void BackgroundFetchJobController::DidGetNextRequest( | 306 void BackgroundFetchJobController::DidGetNextRequest( |
| 286 scoped_refptr<BackgroundFetchRequestInfo> request) { | 307 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 308 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 287 DCHECK_LE(pending_completed_file_acknowledgements_, 1); | 309 DCHECK_LE(pending_completed_file_acknowledgements_, 1); |
| 288 pending_completed_file_acknowledgements_--; | 310 pending_completed_file_acknowledgements_--; |
| 289 | 311 |
| 290 // If a |request| has been given, start downloading the file and bail. | 312 // If a |request| has been given, start downloading the file and bail. |
| 291 if (request) { | 313 if (request) { |
| 292 StartRequest(std::move(request)); | 314 StartRequest(std::move(request)); |
| 293 return; | 315 return; |
| 294 } | 316 } |
| 295 | 317 |
| 296 // If there are outstanding completed file acknowlegements, bail as well. | 318 // If there are outstanding completed file acknowlegements, bail as well. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 314 | 336 |
| 315 // TODO(harkness): Abort all in-progress downloads. | 337 // TODO(harkness): Abort all in-progress downloads. |
| 316 | 338 |
| 317 state_ = State::ABORTED; | 339 state_ = State::ABORTED; |
| 318 | 340 |
| 319 // Inform the owner of the controller about the job having completed. | 341 // Inform the owner of the controller about the job having completed. |
| 320 std::move(completed_callback_).Run(this); | 342 std::move(completed_callback_).Run(this); |
| 321 } | 343 } |
| 322 | 344 |
| 323 } // namespace content | 345 } // namespace content |
| OLD | NEW |