| 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 11 matching lines...) Expand all Loading... |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 // Records the final request status UMA for an offlining request. This should | 24 // Records the final request status UMA for an offlining request. This should |
| 25 // only be called once per Offliner::LoadAndSave request. | 25 // only be called once per Offliner::LoadAndSave request. |
| 26 void RecordOfflinerResultUMA(Offliner::RequestStatus request_status) { | 26 void RecordOfflinerResultUMA(Offliner::RequestStatus request_status) { |
| 27 UMA_HISTOGRAM_ENUMERATION("OfflinePages.Background.OfflinerRequestStatus", | 27 UMA_HISTOGRAM_ENUMERATION("OfflinePages.Background.OfflinerRequestStatus", |
| 28 request_status, | 28 request_status, |
| 29 Offliner::RequestStatus::STATUS_COUNT); | 29 Offliner::RequestStatus::STATUS_COUNT); |
| 30 } | 30 } |
| 31 | 31 |
| 32 // Timeout is 2.5 minutes based on the size of Marshmallow doze mode | |
| 33 // maintenance window (3 minutes) | |
| 34 // TODO(petewil): Find the optimal timeout based on data for 2G connections and | |
| 35 // common EM websites. crbug.com/625204 | |
| 36 // TODO(petewil): Move this value into the policy object. | |
| 37 long OFFLINER_TIMEOUT_SECONDS = 150; | |
| 38 | |
| 39 } // namespace | 32 } // namespace |
| 40 | 33 |
| 41 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy, | 34 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy, |
| 42 std::unique_ptr<OfflinerFactory> factory, | 35 std::unique_ptr<OfflinerFactory> factory, |
| 43 std::unique_ptr<RequestQueue> queue, | 36 std::unique_ptr<RequestQueue> queue, |
| 44 std::unique_ptr<Scheduler> scheduler) | 37 std::unique_ptr<Scheduler> scheduler) |
| 45 : is_busy_(false), | 38 : is_busy_(false), |
| 46 is_canceled_(false), | 39 is_canceled_(false), |
| 47 offliner_timeout_(base::TimeDelta::FromSeconds(OFFLINER_TIMEOUT_SECONDS)), | |
| 48 offliner_(nullptr), | 40 offliner_(nullptr), |
| 49 policy_(std::move(policy)), | 41 policy_(std::move(policy)), |
| 50 factory_(std::move(factory)), | 42 factory_(std::move(factory)), |
| 51 queue_(std::move(queue)), | 43 queue_(std::move(queue)), |
| 52 scheduler_(std::move(scheduler)), | 44 scheduler_(std::move(scheduler)), |
| 53 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), | 45 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), |
| 46 offliner_timeout_(base::TimeDelta::FromSeconds( |
| 47 policy_->GetSinglePageTimeLimitInSeconds())), |
| 54 weak_ptr_factory_(this) { | 48 weak_ptr_factory_(this) { |
| 55 DCHECK(policy_ != nullptr); | 49 DCHECK(policy_ != nullptr); |
| 56 picker_.reset(new RequestPicker(queue_.get(), policy_.get())); | 50 picker_.reset(new RequestPicker(queue_.get(), policy_.get())); |
| 57 } | 51 } |
| 58 | 52 |
| 59 RequestCoordinator::~RequestCoordinator() {} | 53 RequestCoordinator::~RequestCoordinator() {} |
| 60 | 54 |
| 61 bool RequestCoordinator::SavePageLater( | 55 bool RequestCoordinator::SavePageLater( |
| 62 const GURL& url, const ClientId& client_id, bool was_user_requested) { | 56 const GURL& url, const ClientId& client_id, bool was_user_requested) { |
| 63 DVLOG(2) << "URL is " << url << " " << __FUNCTION__; | 57 DVLOG(2) << "URL is " << url << " " << __FUNCTION__; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 } | 108 } |
| 115 | 109 |
| 116 // Returns true if the caller should expect a callback, false otherwise. For | 110 // Returns true if the caller should expect a callback, false otherwise. For |
| 117 // instance, this would return false if a request is already in progress. | 111 // instance, this would return false if a request is already in progress. |
| 118 bool RequestCoordinator::StartProcessing( | 112 bool RequestCoordinator::StartProcessing( |
| 119 const DeviceConditions& device_conditions, | 113 const DeviceConditions& device_conditions, |
| 120 const base::Callback<void(bool)>& callback) { | 114 const base::Callback<void(bool)>& callback) { |
| 121 current_conditions_.reset(new DeviceConditions(device_conditions)); | 115 current_conditions_.reset(new DeviceConditions(device_conditions)); |
| 122 if (is_busy_) return false; | 116 if (is_busy_) return false; |
| 123 | 117 |
| 118 // Mark the time at which we started processing so we can check our time |
| 119 // budget. |
| 120 operation_start_time_ = base::Time::Now(); |
| 121 |
| 124 is_canceled_ = false; | 122 is_canceled_ = false; |
| 125 scheduler_callback_ = callback; | 123 scheduler_callback_ = callback; |
| 126 // TODO(petewil): Check existing conditions (should be passed down from | 124 // TODO(petewil): Check existing conditions (should be passed down from |
| 127 // BackgroundTask) | 125 // BackgroundTask) |
| 128 | 126 |
| 129 TryNextRequest(); | 127 TryNextRequest(); |
| 130 | 128 |
| 131 return true; | 129 return true; |
| 132 } | 130 } |
| 133 | 131 |
| 134 void RequestCoordinator::TryNextRequest() { | 132 void RequestCoordinator::TryNextRequest() { |
| 133 // If there is no time left in the budget, return to the scheduler. |
| 134 // We do not remove the pending task that was set up earlier in case |
| 135 // we run out of time, so the background scheduler will return to us |
| 136 // at the next opportunity to run background tasks. |
| 137 if (base::Time::Now() - operation_start_time_ > |
| 138 base::TimeDelta::FromSeconds( |
| 139 policy_->GetBackgroundProcessingTimeBudgetSeconds())) { |
| 140 // Let the scheduler know we are done processing. |
| 141 scheduler_callback_.Run(true); |
| 142 |
| 143 return; |
| 144 } |
| 145 |
| 135 // Choose a request to process that meets the available conditions. | 146 // Choose a request to process that meets the available conditions. |
| 136 // This is an async call, and returns right away. | 147 // This is an async call, and returns right away. |
| 137 picker_->ChooseNextRequest( | 148 picker_->ChooseNextRequest( |
| 138 base::Bind(&RequestCoordinator::RequestPicked, | 149 base::Bind(&RequestCoordinator::RequestPicked, |
| 139 weak_ptr_factory_.GetWeakPtr()), | 150 weak_ptr_factory_.GetWeakPtr()), |
| 140 base::Bind(&RequestCoordinator::RequestQueueEmpty, | 151 base::Bind(&RequestCoordinator::RequestQueueEmpty, |
| 141 weak_ptr_factory_.GetWeakPtr()), | 152 weak_ptr_factory_.GetWeakPtr()), |
| 142 current_conditions_.get()); | 153 current_conditions_.get()); |
| 143 } | 154 } |
| 144 | 155 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 updated_request.set_last_attempt_time(base::Time::Now()); | 226 updated_request.set_last_attempt_time(base::Time::Now()); |
| 216 RequestQueue::UpdateRequestCallback update_callback = | 227 RequestQueue::UpdateRequestCallback update_callback = |
| 217 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 228 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 218 weak_ptr_factory_.GetWeakPtr()); | 229 weak_ptr_factory_.GetWeakPtr()); |
| 219 queue_->UpdateRequest( | 230 queue_->UpdateRequest( |
| 220 updated_request, | 231 updated_request, |
| 221 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 232 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 222 weak_ptr_factory_.GetWeakPtr())); | 233 weak_ptr_factory_.GetWeakPtr())); |
| 223 } | 234 } |
| 224 | 235 |
| 225 // TODO(petewil): Check time budget. Return to the scheduler if we are out. | |
| 226 // Start another request if we have time. | |
| 227 TryNextRequest(); | 236 TryNextRequest(); |
| 228 } | 237 } |
| 229 | 238 |
| 230 const Scheduler::TriggerConditions | 239 const Scheduler::TriggerConditions |
| 231 RequestCoordinator::GetTriggerConditionsForUserRequest() { | 240 RequestCoordinator::GetTriggerConditionsForUserRequest() { |
| 232 Scheduler::TriggerConditions trigger_conditions( | 241 Scheduler::TriggerConditions trigger_conditions( |
| 233 policy_->PowerRequiredForUserRequestedPage(), | 242 policy_->PowerRequiredForUserRequestedPage(), |
| 234 policy_->BatteryPercentageRequiredForUserRequestedPage(), | 243 policy_->BatteryPercentageRequiredForUserRequestedPage(), |
| 235 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); | 244 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); |
| 236 return trigger_conditions; | 245 return trigger_conditions; |
| 237 } | 246 } |
| 238 | 247 |
| 239 void RequestCoordinator::GetOffliner() { | 248 void RequestCoordinator::GetOffliner() { |
| 240 if (!offliner_) { | 249 if (!offliner_) { |
| 241 offliner_ = factory_->GetOffliner(policy_.get()); | 250 offliner_ = factory_->GetOffliner(policy_.get()); |
| 242 } | 251 } |
| 243 } | 252 } |
| 244 | 253 |
| 245 } // namespace offline_pages | 254 } // namespace offline_pages |
| OLD | NEW |