Chromium Code Reviews| 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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 // be unsafe to obtain a weak pointer on the IO thread from a factory that | 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 | 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. | 255 // can't be destroyed before this constructor finishes. |
| 256 ui_core_ptr_ = ui_core_->GetWeakPtrOnUI(); | 256 ui_core_ptr_ = ui_core_->GetWeakPtrOnUI(); |
| 257 } | 257 } |
| 258 | 258 |
| 259 BackgroundFetchJobController::~BackgroundFetchJobController() { | 259 BackgroundFetchJobController::~BackgroundFetchJobController() { |
| 260 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 260 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 261 }; | 261 }; |
| 262 | 262 |
| 263 void BackgroundFetchJobController::Start( | 263 void BackgroundFetchJobController::Start() { |
| 264 std::vector<scoped_refptr<BackgroundFetchRequestInfo>> initial_requests) { | |
| 265 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 264 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 266 DCHECK_LE(initial_requests.size(), kMaximumBackgroundFetchParallelRequests); | |
| 267 DCHECK_EQ(state_, State::INITIALIZED); | 265 DCHECK_EQ(state_, State::INITIALIZED); |
| 268 | 266 |
| 269 state_ = State::FETCHING; | 267 state_ = State::FETCHING; |
| 270 | 268 |
| 271 for (const auto& request : initial_requests) | 269 // TODO(johnme): Enforce kMaximumBackgroundFetchParallelRequests globally |
| 272 StartRequest(request); | 270 // and/or per origin rather than per fetch (crbug.com/741609). |
|
Peter Beverloo
2017/07/12 13:30:50
note: TODO(crbug.com/123456) is allowed syntax, an
johnme
2017/07/12 14:13:58
Done.
| |
| 271 for (size_t i = 0; i < kMaximumBackgroundFetchParallelRequests; i++) { | |
| 272 data_manager_->PopNextRequest( | |
| 273 registration_id_, | |
| 274 base::BindOnce(&BackgroundFetchJobController::StartRequest, | |
| 275 weak_ptr_factory_.GetWeakPtr())); | |
| 276 } | |
| 273 } | 277 } |
| 274 | 278 |
| 275 void BackgroundFetchJobController::StartRequest( | 279 void BackgroundFetchJobController::StartRequest( |
| 276 scoped_refptr<BackgroundFetchRequestInfo> request) { | 280 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 277 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 281 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 278 DCHECK_EQ(state_, State::FETCHING); | 282 DCHECK_EQ(state_, State::FETCHING); |
| 283 if (!request) { | |
| 284 // This can happen when |Start| tries to start multiple initial requests, | |
| 285 // but the fetch does not contain that many pending requests; or when | |
| 286 // |DidMarkRequestCompleted| tries to start the next request but there are | |
| 287 // none left. | |
| 288 return; | |
| 289 } | |
| 279 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 290 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 280 base::Bind(&Core::StartRequest, ui_core_ptr_, | 291 base::Bind(&Core::StartRequest, ui_core_ptr_, |
| 281 std::move(request), traffic_annotation_)); | 292 std::move(request), traffic_annotation_)); |
| 282 } | 293 } |
| 283 | 294 |
| 284 void BackgroundFetchJobController::DidStartRequest( | 295 void BackgroundFetchJobController::DidStartRequest( |
| 285 scoped_refptr<BackgroundFetchRequestInfo> request, | 296 scoped_refptr<BackgroundFetchRequestInfo> request, |
| 286 const std::string& download_guid) { | 297 const std::string& download_guid) { |
| 287 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 298 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 288 data_manager_->MarkRequestAsStarted(registration_id_, request.get(), | 299 data_manager_->MarkRequestAsStarted(registration_id_, request.get(), |
| 289 download_guid); | 300 download_guid); |
| 290 } | 301 } |
| 291 | 302 |
| 292 void BackgroundFetchJobController::DidCompleteRequest( | 303 void BackgroundFetchJobController::DidCompleteRequest( |
| 293 scoped_refptr<BackgroundFetchRequestInfo> request) { | 304 scoped_refptr<BackgroundFetchRequestInfo> request) { |
| 294 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 305 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 295 | 306 |
| 296 // The DataManager must acknowledge that it stored the data and that there are | 307 // The DataManager must acknowledge that it stored the data and that there are |
| 297 // no more pending requests to avoid marking this job as completed too early. | 308 // no more pending requests to avoid marking this job as completed too early. |
| 298 pending_completed_file_acknowledgements_++; | 309 data_manager_->MarkRequestAsComplete( |
| 299 | |
| 300 data_manager_->MarkRequestAsCompleteAndGetNextRequest( | |
| 301 registration_id_, request.get(), | 310 registration_id_, request.get(), |
| 302 base::BindOnce(&BackgroundFetchJobController::DidGetNextRequest, | 311 base::BindOnce(&BackgroundFetchJobController::DidMarkRequestCompleted, |
| 303 weak_ptr_factory_.GetWeakPtr())); | 312 weak_ptr_factory_.GetWeakPtr())); |
| 304 } | 313 } |
| 305 | 314 |
| 306 void BackgroundFetchJobController::DidGetNextRequest( | 315 void BackgroundFetchJobController::DidMarkRequestCompleted( |
| 307 scoped_refptr<BackgroundFetchRequestInfo> request) { | 316 bool has_pending_or_active_requests) { |
| 308 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 317 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 309 DCHECK_LE(pending_completed_file_acknowledgements_, 1); | 318 DCHECK_EQ(state_, State::FETCHING); |
| 310 pending_completed_file_acknowledgements_--; | |
| 311 | 319 |
| 312 // If a |request| has been given, start downloading the file and bail. | 320 // If not all requests have completed, start a pending request if there are |
| 313 if (request) { | 321 // any left, and bail. |
| 314 StartRequest(std::move(request)); | 322 if (has_pending_or_active_requests) { |
| 323 data_manager_->PopNextRequest( | |
| 324 registration_id_, | |
| 325 base::BindOnce(&BackgroundFetchJobController::StartRequest, | |
| 326 weak_ptr_factory_.GetWeakPtr())); | |
| 315 return; | 327 return; |
| 316 } | 328 } |
| 317 | 329 |
| 318 // If there are outstanding completed file acknowlegements, bail as well. | 330 // Otherwise the job this controller is responsible for has completed. |
| 319 if (pending_completed_file_acknowledgements_ > 0) | |
| 320 return; | |
| 321 | |
| 322 state_ = State::COMPLETED; | 331 state_ = State::COMPLETED; |
| 323 | |
| 324 // Otherwise the job this controller is responsible for has completed. | |
| 325 std::move(completed_callback_).Run(this); | 332 std::move(completed_callback_).Run(this); |
| 333 completed_callback_.Reset(); | |
| 326 } | 334 } |
| 327 | 335 |
| 328 void BackgroundFetchJobController::UpdateUI(const std::string& title) { | 336 void BackgroundFetchJobController::UpdateUI(const std::string& title) { |
| 329 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 337 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 330 | 338 |
| 331 // TODO(harkness): Update the user interface with |title|. | 339 // TODO(harkness): Update the user interface with |title|. |
| 332 } | 340 } |
| 333 | 341 |
| 334 void BackgroundFetchJobController::Abort() { | 342 void BackgroundFetchJobController::Abort() { |
| 335 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 343 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 344 DCHECK_EQ(state_, State::FETCHING); | |
|
Peter Beverloo
2017/07/12 13:30:50
Hmm. Might we end up with a scheduling solution wh
johnme
2017/07/12 14:13:58
Good point. Changed this to just early out if stat
| |
| 336 | 345 |
| 337 // TODO(harkness): Abort all in-progress downloads. | 346 // TODO(harkness): Abort all in-progress downloads. |
| 338 | 347 |
| 339 state_ = State::ABORTED; | 348 state_ = State::ABORTED; |
| 340 | 349 // Inform the owner of the controller about the job having aborted. |
| 341 // Inform the owner of the controller about the job having completed. | |
| 342 std::move(completed_callback_).Run(this); | 350 std::move(completed_callback_).Run(this); |
| 351 completed_callback_.Reset(); | |
|
Peter Beverloo
2017/07/12 13:30:50
delete, that's what std::move() will conceptually
johnme
2017/07/12 14:13:58
Done.
| |
| 343 } | 352 } |
| 344 | 353 |
| 345 } // namespace content | 354 } // namespace content |
| OLD | NEW |