Chromium Code Reviews| 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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "components/offline_pages/background/offliner_factory.h" | 15 #include "components/offline_pages/background/offliner_factory.h" |
| 16 #include "components/offline_pages/background/offliner_policy.h" | 16 #include "components/offline_pages/background/offliner_policy.h" |
| 17 #include "components/offline_pages/background/request_picker.h" | 17 #include "components/offline_pages/background/request_picker.h" |
| 18 #include "components/offline_pages/background/save_page_request.h" | 18 #include "components/offline_pages/background/save_page_request.h" |
| 19 #include "components/offline_pages/offline_page_item.h" | 19 #include "components/offline_pages/offline_page_item.h" |
| 20 #include "components/offline_pages/offline_page_model.h" | 20 #include "components/offline_pages/offline_page_model.h" |
| 21 | 21 |
| 22 namespace offline_pages { | 22 namespace offline_pages { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 const bool kNonUserRequest = false; | |
| 25 | 26 |
| 26 // Records the final request status UMA for an offlining request. This should | 27 // Records the final request status UMA for an offlining request. This should |
| 27 // only be called once per Offliner::LoadAndSave request. | 28 // only be called once per Offliner::LoadAndSave request. |
| 28 void RecordOfflinerResultUMA(const ClientId& client_id, | 29 void RecordOfflinerResultUMA(const ClientId& client_id, |
| 29 Offliner::RequestStatus request_status) { | 30 Offliner::RequestStatus request_status) { |
| 30 // TODO(dougarnett): Consider exposing AddHistogramSuffix from | 31 // TODO(dougarnett): Consider exposing AddHistogramSuffix from |
| 31 // offline_page_model_impl.cc as visible utility method. | 32 // offline_page_model_impl.cc as visible utility method. |
| 32 std::string histogram_name("OfflinePages.Background.OfflinerRequestStatus"); | 33 std::string histogram_name("OfflinePages.Background.OfflinerRequestStatus"); |
| 33 if (!client_id.name_space.empty()) { | 34 if (!client_id.name_space.empty()) { |
| 34 histogram_name += "." + client_id.name_space; | 35 histogram_name += "." + client_id.name_space; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 weak_ptr_factory_.GetWeakPtr(), callback)); | 106 weak_ptr_factory_.GetWeakPtr(), callback)); |
| 106 } | 107 } |
| 107 | 108 |
| 108 void RequestCoordinator::GetQueuedRequestsCallback( | 109 void RequestCoordinator::GetQueuedRequestsCallback( |
| 109 const GetRequestsCallback& callback, | 110 const GetRequestsCallback& callback, |
| 110 RequestQueue::GetRequestsResult result, | 111 RequestQueue::GetRequestsResult result, |
| 111 const std::vector<SavePageRequest>& requests) { | 112 const std::vector<SavePageRequest>& requests) { |
| 112 callback.Run(requests); | 113 callback.Run(requests); |
| 113 } | 114 } |
| 114 | 115 |
| 116 void RequestCoordinator::GetRequestsForSchedulingCallback( | |
| 117 RequestQueue::GetRequestsResult result, | |
| 118 const std::vector<SavePageRequest>& requests) { | |
| 119 bool user_requested = false; | |
| 120 | |
| 121 // Examine all requests, if we find a user requested one, we will use the less | |
| 122 // restrictive conditions for user_requested requests. Otherwise we will use | |
| 123 // the more restrictive non-user-requested conditions. | |
| 124 for (const SavePageRequest& request : requests) { | |
| 125 if (request.user_requested()) { | |
| 126 user_requested = true; | |
| 127 break; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 // In the get callback, determine the least restrictive, and call | |
| 132 // GetTriggerConditions based on that. | |
| 133 scheduler_->Schedule(GetTriggerConditions(user_requested)); | |
| 134 } | |
| 135 | |
| 115 void RequestCoordinator::RemoveRequests( | 136 void RequestCoordinator::RemoveRequests( |
| 116 const std::vector<int64_t>& request_ids) { | 137 const std::vector<int64_t>& request_ids) { |
| 117 queue_->RemoveRequests(request_ids, | 138 queue_->RemoveRequests(request_ids, |
| 118 base::Bind(&RequestCoordinator::RemoveRequestsCallback, | 139 base::Bind(&RequestCoordinator::RemoveRequestsCallback, |
| 119 weak_ptr_factory_.GetWeakPtr())); | 140 weak_ptr_factory_.GetWeakPtr())); |
| 120 } | 141 } |
| 121 | 142 |
| 122 void RequestCoordinator::PauseRequests( | 143 void RequestCoordinator::PauseRequests( |
| 123 const std::vector<int64_t>& request_ids) { | 144 const std::vector<int64_t>& request_ids) { |
| 124 queue_->ChangeRequestsState( | 145 queue_->ChangeRequestsState( |
| 125 request_ids, SavePageRequest::RequestState::PAUSED, | 146 request_ids, SavePageRequest::RequestState::PAUSED, |
| 126 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, | 147 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, |
| 127 weak_ptr_factory_.GetWeakPtr())); | 148 weak_ptr_factory_.GetWeakPtr())); |
| 128 } | 149 } |
| 129 | 150 |
| 130 void RequestCoordinator::ResumeRequests( | 151 void RequestCoordinator::ResumeRequests( |
| 131 const std::vector<int64_t>& request_ids) { | 152 const std::vector<int64_t>& request_ids) { |
| 132 queue_->ChangeRequestsState( | 153 queue_->ChangeRequestsState( |
| 133 request_ids, SavePageRequest::RequestState::AVAILABLE, | 154 request_ids, SavePageRequest::RequestState::AVAILABLE, |
| 134 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, | 155 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, |
| 135 weak_ptr_factory_.GetWeakPtr())); | 156 weak_ptr_factory_.GetWeakPtr())); |
| 136 // TODO: Should we also schedule a task, in case there is not one scheduled? | 157 // Schedule a task, in case there is not one scheduled. |
| 158 ScheduleAsNeeded(); | |
| 137 } | 159 } |
| 138 | 160 |
| 139 void RequestCoordinator::AddRequestResultCallback( | 161 void RequestCoordinator::AddRequestResultCallback( |
| 140 RequestQueue::AddRequestResult result, | 162 RequestQueue::AddRequestResult result, |
| 141 const SavePageRequest& request) { | 163 const SavePageRequest& request) { |
| 142 // Inform the scheduler that we have an outstanding task.. | 164 // Inform the scheduler that we have an outstanding task.. |
| 143 scheduler_->Schedule(GetTriggerConditionsForUserRequest()); | 165 ScheduleAsNeeded(); |
| 144 } | 166 } |
| 145 | 167 |
| 146 // Called in response to updating a request in the request queue. | 168 // Called in response to updating a request in the request queue. |
| 147 void RequestCoordinator::UpdateRequestCallback( | 169 void RequestCoordinator::UpdateRequestCallback( |
| 148 const ClientId& client_id, | 170 const ClientId& client_id, |
| 149 RequestQueue::UpdateRequestResult result) { | 171 RequestQueue::UpdateRequestResult result) { |
| 150 // If the request succeeded, nothing to do. If it failed, we can't really do | 172 // If the request succeeded, nothing to do. If it failed, we can't really do |
| 151 // much, so just log it. | 173 // much, so just log it. |
| 152 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { | 174 if (result != RequestQueue::UpdateRequestResult::SUCCESS) { |
| 153 DVLOG(1) << "Failed to update request attempt details. " | 175 DVLOG(1) << "Failed to update request attempt details. " |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 164 NotifyChanged(request); | 186 NotifyChanged(request); |
| 165 } | 187 } |
| 166 | 188 |
| 167 void RequestCoordinator::RemoveRequestsCallback( | 189 void RequestCoordinator::RemoveRequestsCallback( |
| 168 const RequestQueue::UpdateMultipleRequestResults& results, | 190 const RequestQueue::UpdateMultipleRequestResults& results, |
| 169 const std::vector<SavePageRequest>& requests) { | 191 const std::vector<SavePageRequest>& requests) { |
| 170 for (SavePageRequest request : requests) | 192 for (SavePageRequest request : requests) |
| 171 NotifyCompleted(request, SavePageStatus::REMOVED); | 193 NotifyCompleted(request, SavePageStatus::REMOVED); |
| 172 } | 194 } |
| 173 | 195 |
| 196 void RequestCoordinator::ScheduleAsNeeded() { | |
| 197 // Get all requests from queue (there is no filtering mechanism). | |
| 198 queue_->GetRequests( | |
| 199 base::Bind(&RequestCoordinator::GetRequestsForSchedulingCallback, | |
| 200 weak_ptr_factory_.GetWeakPtr())); | |
| 201 } | |
| 202 | |
| 174 void RequestCoordinator::StopProcessing() { | 203 void RequestCoordinator::StopProcessing() { |
| 175 is_canceled_ = true; | 204 is_canceled_ = true; |
| 176 if (offliner_ && is_busy_) { | 205 if (offliner_ && is_busy_) { |
| 177 // TODO(dougarnett): Find current request and mark attempt aborted. | 206 // TODO(dougarnett): Find current request and mark attempt aborted. |
| 178 offliner_->Cancel(); | 207 offliner_->Cancel(); |
| 179 } | 208 } |
| 180 | 209 |
| 181 // Stopping offliner means it will not call callback. | 210 // Stopping offliner means it will not call callback. |
| 182 last_offlining_status_ = | 211 last_offlining_status_ = |
| 183 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; | 212 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 weak_ptr_factory_.GetWeakPtr()), | 264 weak_ptr_factory_.GetWeakPtr()), |
| 236 current_conditions_.get()); | 265 current_conditions_.get()); |
| 237 } | 266 } |
| 238 | 267 |
| 239 // Called by the request picker when a request has been picked. | 268 // Called by the request picker when a request has been picked. |
| 240 void RequestCoordinator::RequestPicked(const SavePageRequest& request) { | 269 void RequestCoordinator::RequestPicked(const SavePageRequest& request) { |
| 241 // Send the request on to the offliner. | 270 // Send the request on to the offliner. |
| 242 SendRequestToOffliner(request); | 271 SendRequestToOffliner(request); |
| 243 } | 272 } |
| 244 | 273 |
| 245 void RequestCoordinator::RequestQueueEmpty() { | 274 void RequestCoordinator::RequestQueueEmpty( |
|
dougarnett
2016/08/24 17:32:01
RequestNotPicked?
Pete Williamson
2016/08/25 00:00:58
Done.
| |
| 275 bool non_user_requested_tasks_remaining) { | |
| 246 // Clear the outstanding "safety" task in the scheduler. | 276 // Clear the outstanding "safety" task in the scheduler. |
| 247 scheduler_->Unschedule(); | 277 scheduler_->Unschedule(); |
| 278 | |
| 279 if (non_user_requested_tasks_remaining) { | |
|
fgorski
2016/08/24 16:07:04
nit: drop {}
Pete Williamson
2016/08/25 00:00:58
Done.
| |
| 280 scheduler_->Schedule(GetTriggerConditions(kNonUserRequest)); | |
|
dougarnett
2016/08/24 17:32:01
nit - harder to read than !kUserRequested
Pete Williamson
2016/08/25 00:00:58
Done.
| |
| 281 } | |
| 248 // Let the scheduler know we are done processing. | 282 // Let the scheduler know we are done processing. |
| 249 scheduler_callback_.Run(true); | 283 scheduler_callback_.Run(true); |
| 250 } | 284 } |
| 251 | 285 |
| 252 void RequestCoordinator::SendRequestToOffliner(const SavePageRequest& request) { | 286 void RequestCoordinator::SendRequestToOffliner(const SavePageRequest& request) { |
| 253 // Check that offlining didn't get cancelled while performing some async | 287 // Check that offlining didn't get cancelled while performing some async |
| 254 // steps. | 288 // steps. |
| 255 if (is_canceled_) | 289 if (is_canceled_) |
| 256 return; | 290 return; |
| 257 | 291 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 case Offliner::RequestStatus::PRERENDERING_FAILED: | 401 case Offliner::RequestStatus::PRERENDERING_FAILED: |
| 368 // No further processing in this service window. | 402 // No further processing in this service window. |
| 369 break; | 403 break; |
| 370 default: | 404 default: |
| 371 // Make explicit choice about new status codes that actually reach here. | 405 // Make explicit choice about new status codes that actually reach here. |
| 372 // Their default is no further processing in this service window. | 406 // Their default is no further processing in this service window. |
| 373 DCHECK(false); | 407 DCHECK(false); |
| 374 } | 408 } |
| 375 } | 409 } |
| 376 | 410 |
| 377 const Scheduler::TriggerConditions | 411 const Scheduler::TriggerConditions RequestCoordinator::GetTriggerConditions( |
| 378 RequestCoordinator::GetTriggerConditionsForUserRequest() { | 412 const bool user_requested) { |
| 379 Scheduler::TriggerConditions trigger_conditions( | 413 bool power = policy_->PowerRequiredForUserRequestedPage(); |
|
fgorski
2016/08/24 16:07:04
Here is an idea: how about policy_->PowerRequired(
Pete Williamson
2016/08/25 00:00:58
Done.
| |
| 380 policy_->PowerRequiredForUserRequestedPage(), | 414 int battery = policy_->BatteryPercentageRequiredForUserRequestedPage(); |
| 381 policy_->BatteryPercentageRequiredForUserRequestedPage(), | 415 bool unmetered = policy_->UnmeteredNetworkRequiredForUserRequestedPage(); |
| 382 policy_->UnmeteredNetworkRequiredForUserRequestedPage()); | 416 |
| 417 if (!user_requested) { | |
| 418 power = policy_->PowerRequiredForNonUserRequestedPage(); | |
| 419 battery = policy_->BatteryPercentageRequiredForNonUserRequestedPage(); | |
| 420 unmetered = policy_->UnmeteredNetworkRequiredForNonUserRequestedPage(); | |
| 421 } | |
| 422 | |
| 423 Scheduler::TriggerConditions trigger_conditions(power, battery, unmetered); | |
|
fgorski
2016/08/24 16:07:04
Can you return from here?
return Scheduler::Trigg
Pete Williamson
2016/08/25 00:00:58
Done.
| |
| 424 | |
| 383 return trigger_conditions; | 425 return trigger_conditions; |
| 384 } | 426 } |
| 385 | 427 |
| 386 void RequestCoordinator::AddObserver(Observer* observer) { | 428 void RequestCoordinator::AddObserver(Observer* observer) { |
| 387 DCHECK(observer); | 429 DCHECK(observer); |
| 388 observers_.AddObserver(observer); | 430 observers_.AddObserver(observer); |
| 389 } | 431 } |
| 390 | 432 |
| 391 void RequestCoordinator::RemoveObserver(Observer* observer) { | 433 void RequestCoordinator::RemoveObserver(Observer* observer) { |
| 392 observers_.RemoveObserver(observer); | 434 observers_.RemoveObserver(observer); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 405 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); | 447 FOR_EACH_OBSERVER(Observer, observers_, OnChanged(request)); |
| 406 } | 448 } |
| 407 | 449 |
| 408 void RequestCoordinator::GetOffliner() { | 450 void RequestCoordinator::GetOffliner() { |
| 409 if (!offliner_) { | 451 if (!offliner_) { |
| 410 offliner_ = factory_->GetOffliner(policy_.get()); | 452 offliner_ = factory_->GetOffliner(policy_.get()); |
| 411 } | 453 } |
| 412 } | 454 } |
| 413 | 455 |
| 414 } // namespace offline_pages | 456 } // namespace offline_pages |
| OLD | NEW |