| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "components/offline_pages/background/request_coordinator.h" | 5 #include "components/offline_pages/background/request_coordinator.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 static int64_t id = 0; | 81 static int64_t id = 0; |
| 82 | 82 |
| 83 // Build a SavePageRequest. | 83 // Build a SavePageRequest. |
| 84 offline_pages::SavePageRequest request( | 84 offline_pages::SavePageRequest request( |
| 85 id++, url, client_id, base::Time::Now(), was_user_requested); | 85 id++, url, client_id, base::Time::Now(), was_user_requested); |
| 86 | 86 |
| 87 // Put the request on the request queue. | 87 // Put the request on the request queue. |
| 88 queue_->AddRequest(request, | 88 queue_->AddRequest(request, |
| 89 base::Bind(&RequestCoordinator::AddRequestResultCallback, | 89 base::Bind(&RequestCoordinator::AddRequestResultCallback, |
| 90 weak_ptr_factory_.GetWeakPtr())); | 90 weak_ptr_factory_.GetWeakPtr())); |
| 91 NotifyAvailable(client_id); |
| 91 return true; | 92 return true; |
| 92 } | 93 } |
| 93 void RequestCoordinator::GetQueuedRequests( | 94 void RequestCoordinator::GetQueuedRequests( |
| 94 const std::string& client_namespace, | 95 const std::string& client_namespace, |
| 95 const QueuedRequestCallback& callback) { | 96 const QueuedRequestCallback& callback) { |
| 96 // Get all matching requests from the request queue, send them to our | 97 // Get all matching requests from the request queue, send them to our |
| 97 // callback. We bind the namespace and callback to the front of the callback | 98 // callback. We bind the namespace and callback to the front of the callback |
| 98 // param set. | 99 // param set. |
| 99 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, | 100 queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, |
| 100 weak_ptr_factory_.GetWeakPtr(), | 101 weak_ptr_factory_.GetWeakPtr(), |
| (...skipping 21 matching lines...) Expand all Loading... |
| 122 queue_->RemoveRequestsByClientId( | 123 queue_->RemoveRequestsByClientId( |
| 123 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, | 124 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, |
| 124 weak_ptr_factory_.GetWeakPtr())); | 125 weak_ptr_factory_.GetWeakPtr())); |
| 125 } | 126 } |
| 126 | 127 |
| 127 void RequestCoordinator::PauseRequests( | 128 void RequestCoordinator::PauseRequests( |
| 128 const std::vector<ClientId>& client_ids) { | 129 const std::vector<ClientId>& client_ids) { |
| 129 queue_->PauseRequestsByClientId( | 130 queue_->PauseRequestsByClientId( |
| 130 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, | 131 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, |
| 131 weak_ptr_factory_.GetWeakPtr())); | 132 weak_ptr_factory_.GetWeakPtr())); |
| 133 for(ClientId client_id : client_ids) |
| 134 NotifyPaused(client_id); |
| 132 } | 135 } |
| 133 | 136 |
| 134 void RequestCoordinator::ResumeRequests( | 137 void RequestCoordinator::ResumeRequests( |
| 135 const std::vector<ClientId>& client_ids) { | 138 const std::vector<ClientId>& client_ids) { |
| 136 queue_->ResumeRequestsByClientId( | 139 queue_->ResumeRequestsByClientId( |
| 137 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, | 140 client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, |
| 138 weak_ptr_factory_.GetWeakPtr())); | 141 weak_ptr_factory_.GetWeakPtr())); |
| 139 // TODO: Should we also schedule a task, in case there is not one scheduled? | 142 // TODO: Should we also schedule a task, in case there is not one scheduled? |
| 143 for (ClientId client_id : client_ids) |
| 144 NotifyAvailable(client_id); |
| 140 } | 145 } |
| 141 | 146 |
| 142 void RequestCoordinator::AddRequestResultCallback( | 147 void RequestCoordinator::AddRequestResultCallback( |
| 143 RequestQueue::AddRequestResult result, | 148 RequestQueue::AddRequestResult result, |
| 144 const SavePageRequest& request) { | 149 const SavePageRequest& request) { |
| 145 | |
| 146 // Inform the scheduler that we have an outstanding task.. | 150 // Inform the scheduler that we have an outstanding task.. |
| 147 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); | 151 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); |
| 148 } | 152 } |
| 149 | 153 |
| 150 // Called in response to updating a request in the request queue. | 154 // Called in response to updating a request in the request queue. |
| 151 void RequestCoordinator::UpdateRequestCallback( | 155 void RequestCoordinator::UpdateRequestCallback( |
| 152 const ClientId& client_id, | 156 const ClientId& client_id, |
| 153 RequestQueue::UpdateRequestResult result) { | 157 RequestQueue::UpdateRequestResult result) { |
| 154 // If the request succeeded, nothing to do. If it failed, we can't really do | 158 // If the request succeeded, nothing to do. If it failed, we can't really do |
| 155 // much, so just log it. | 159 // much, so just log it. |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { | 313 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { |
| 310 // Update the request for the canceled attempt. | 314 // Update the request for the canceled attempt. |
| 311 // TODO(dougarnett): See if we can conclusively identify other attempt | 315 // TODO(dougarnett): See if we can conclusively identify other attempt |
| 312 // aborted cases to treat this way (eg, for Render Process Killed). | 316 // aborted cases to treat this way (eg, for Render Process Killed). |
| 313 SavePageRequest updated_request(request); | 317 SavePageRequest updated_request(request); |
| 314 updated_request.MarkAttemptAborted(); | 318 updated_request.MarkAttemptAborted(); |
| 315 queue_->UpdateRequest(updated_request, | 319 queue_->UpdateRequest(updated_request, |
| 316 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 320 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 317 weak_ptr_factory_.GetWeakPtr(), | 321 weak_ptr_factory_.GetWeakPtr(), |
| 318 updated_request.client_id())); | 322 updated_request.client_id())); |
| 323 NotifyFailed(request.client_id()); |
| 319 | 324 |
| 320 } else if (status == Offliner::RequestStatus::SAVED || | 325 } else if (status == Offliner::RequestStatus::SAVED) { |
| 321 request.completed_attempt_count() + 1 >= | 326 // Remove the request from the queue if it either succeeded. |
| 322 policy_->GetMaxCompletedTries()) { | |
| 323 // Remove the request from the queue if it either succeeded or exceeded the | |
| 324 // max number of retries. The +1 represents the request that just | |
| 325 // completed. Since we call MarkAttemptCompleted within the if branches, | |
| 326 // the completed_attempt_count has not yet been updated when we are checking | |
| 327 // the if condition. | |
| 328 std::vector<ClientId> client_ids; | 327 std::vector<ClientId> client_ids; |
| 329 client_ids.push_back(request.client_id()); | 328 client_ids.push_back(request.client_id()); |
| 330 queue_->RemoveRequestsByClientId( | 329 queue_->RemoveRequestsByClientId( |
| 331 client_ids, | 330 client_ids, |
| 332 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 331 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 333 weak_ptr_factory_.GetWeakPtr(), request.client_id())); | 332 weak_ptr_factory_.GetWeakPtr(), request.client_id())); |
| 333 NotifySucceeded(request.client_id()); |
| 334 } else if (request.completed_attempt_count() + 1 >= |
| 335 policy_->GetMaxCompletedTries()) { |
| 336 // Remove from the request queue if we exceeeded max retries. The +1 |
| 337 // represents the request that just completed. Since we call |
| 338 // MarkAttemptCompleted within the if branches, the completed_attempt_count |
| 339 // has not yet been updated when we are checking the if condition. |
| 340 std::vector<ClientId> client_ids; |
| 341 client_ids.push_back(request.client_id()); |
| 342 queue_->RemoveRequestsByClientId( |
| 343 client_ids, |
| 344 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 345 weak_ptr_factory_.GetWeakPtr(), request.client_id())); |
| 346 NotifyFailed(request.client_id()); |
| 334 } else { | 347 } else { |
| 335 // If we failed, but are not over the limit, update the request in the | 348 // If we failed, but are not over the limit, update the request in the |
| 336 // queue. | 349 // queue. |
| 337 SavePageRequest updated_request(request); | 350 SavePageRequest updated_request(request); |
| 338 updated_request.MarkAttemptCompleted(); | 351 updated_request.MarkAttemptCompleted(); |
| 339 queue_->UpdateRequest(updated_request, | 352 queue_->UpdateRequest(updated_request, |
| 340 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 353 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 341 weak_ptr_factory_.GetWeakPtr(), | 354 weak_ptr_factory_.GetWeakPtr(), |
| 342 updated_request.client_id())); | 355 updated_request.client_id())); |
| 356 NotifyAvailable(request.client_id()); |
| 343 } | 357 } |
| 344 | 358 |
| 345 // Determine whether we might try another request in this | 359 // Determine whether we might try another request in this |
| 346 // processing window based on how the previous request completed. | 360 // processing window based on how the previous request completed. |
| 347 // | 361 // |
| 348 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate | 362 // TODO(dougarnett): Need to split PRERENDERING_FAILED into separate |
| 349 // codes as to whether we should try another request or not. | 363 // codes as to whether we should try another request or not. |
| 350 switch (status) { | 364 switch (status) { |
| 351 case Offliner::RequestStatus::SAVED: | 365 case Offliner::RequestStatus::SAVED: |
| 352 case Offliner::RequestStatus::SAVE_FAILED: | 366 case Offliner::RequestStatus::SAVE_FAILED: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 368 | 382 |
| 369 const Scheduler::TriggerConditions | 383 const Scheduler::TriggerConditions |
| 370 RequestCoordinator::GetTriggerConditionsForUserRequest() { | 384 RequestCoordinator::GetTriggerConditionsForUserRequest() { |
| 371 Scheduler::TriggerConditions trigger_conditions( | 385 Scheduler::TriggerConditions trigger_conditions( |
| 372 policy_->PowerRequiredForUserRequestedPage(), | 386 policy_->PowerRequiredForUserRequestedPage(), |
| 373 policy_->BatteryPercentageRequiredForUserRequestedPage(), | 387 policy_->BatteryPercentageRequiredForUserRequestedPage(), |
| 374 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); | 388 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); |
| 375 return trigger_conditions; | 389 return trigger_conditions; |
| 376 } | 390 } |
| 377 | 391 |
| 392 void RequestCoordinator::AddObserver(Observer* observer) { |
| 393 DCHECK(observer); |
| 394 observers_.AddObserver(observer); |
| 395 } |
| 396 |
| 397 void RequestCoordinator::RemoveObserver(Observer* observer) { |
| 398 observers_.RemoveObserver(observer); |
| 399 } |
| 400 |
| 401 void RequestCoordinator::NotifyAvailable(ClientId client_id) { |
| 402 RequestInfo info; |
| 403 info.client_id = client_id; |
| 404 FOR_EACH_OBSERVER(Observer, observers_, OnAvailable(info)); |
| 405 } |
| 406 |
| 407 void RequestCoordinator::NotifySucceeded(ClientId client_id) { |
| 408 RequestInfo info; |
| 409 info.client_id = client_id;; |
| 410 FOR_EACH_OBSERVER(Observer, observers_, OnSucceeded(info)); |
| 411 } |
| 412 |
| 413 void RequestCoordinator::NotifyFailed(ClientId client_id) { |
| 414 RequestInfo info; |
| 415 info.client_id = client_id; |
| 416 FOR_EACH_OBSERVER(Observer, observers_, OnFailed(info)); |
| 417 } |
| 418 |
| 419 void RequestCoordinator::NotifyPaused(ClientId client_id) { |
| 420 RequestInfo info; |
| 421 info.client_id = client_id; |
| 422 FOR_EACH_OBSERVER(Observer, observers_, OnPaused(info)); |
| 423 } |
| 424 |
| 378 void RequestCoordinator::GetOffliner() { | 425 void RequestCoordinator::GetOffliner() { |
| 379 if (!offliner_) { | 426 if (!offliner_) { |
| 380 offliner_ = factory_->GetOffliner(policy_.get()); | 427 offliner_ = factory_->GetOffliner(policy_.get()); |
| 381 } | 428 } |
| 382 } | 429 } |
| 383 | 430 |
| 384 } // namespace offline_pages | 431 } // namespace offline_pages |
| OLD | NEW |