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/core/background/request_coordinator.h" | 5 #include "components/offline_pages/core/background/request_coordinator.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( | 151 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
152 AddHistogramSuffix( | 152 AddHistogramSuffix( |
153 client_id, | 153 client_id, |
154 "OfflinePages.Background.EffectiveConnectionType.SavePageLater"), | 154 "OfflinePages.Background.EffectiveConnectionType.SavePageLater"), |
155 1, net::EFFECTIVE_CONNECTION_TYPE_LAST - 1, | 155 1, net::EFFECTIVE_CONNECTION_TYPE_LAST - 1, |
156 net::EFFECTIVE_CONNECTION_TYPE_LAST, | 156 net::EFFECTIVE_CONNECTION_TYPE_LAST, |
157 base::HistogramBase::kUmaTargetedHistogramFlag); | 157 base::HistogramBase::kUmaTargetedHistogramFlag); |
158 histogram->Add(effective_connection); | 158 histogram->Add(effective_connection); |
159 } | 159 } |
160 | 160 |
| 161 // Record the network quality at request creation time per namespace. |
| 162 void RecordNetworkQualityAtRequestStartForFailedRequest( |
| 163 const ClientId& client_id, |
| 164 const net::EffectiveConnectionType effective_connection) { |
| 165 // The histogram below is an expansion of the UMA_HISTOGRAM_ENUMERATION |
| 166 // macro adapted to allow for a dynamically suffixed histogram name. |
| 167 // Note: The factory creates and owns the histogram. |
| 168 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
| 169 AddHistogramSuffix( |
| 170 client_id, |
| 171 "OfflinePages.Background.EffectiveConnectionType.OffliningStartType"), |
| 172 1, net::EFFECTIVE_CONNECTION_TYPE_LAST - 1, |
| 173 net::EFFECTIVE_CONNECTION_TYPE_LAST, |
| 174 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 175 histogram->Add(effective_connection); |
| 176 } |
| 177 |
161 // This should use the same algorithm as we use for OfflinePageItem, so the IDs | 178 // This should use the same algorithm as we use for OfflinePageItem, so the IDs |
162 // are similar. | 179 // are similar. |
163 int64_t GenerateOfflineId() { | 180 int64_t GenerateOfflineId() { |
164 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; | 181 return base::RandGenerator(std::numeric_limits<int64_t>::max()) + 1; |
165 } | 182 } |
166 | 183 |
167 // In case we start processing from SavePageLater, we need a callback, but there | 184 // In case we start processing from SavePageLater, we need a callback, but there |
168 // is nothing for it to do. | 185 // is nothing for it to do. |
169 void EmptySchedulerCallback(bool started) {} | 186 void EmptySchedulerCallback(bool started) {} |
170 | 187 |
(...skipping 29 matching lines...) Expand all Loading... |
200 : is_low_end_device_(base::SysInfo::IsLowEndDevice()), | 217 : is_low_end_device_(base::SysInfo::IsLowEndDevice()), |
201 state_(RequestCoordinatorState::IDLE), | 218 state_(RequestCoordinatorState::IDLE), |
202 processing_state_(ProcessingWindowState::STOPPED), | 219 processing_state_(ProcessingWindowState::STOPPED), |
203 use_test_device_conditions_(false), | 220 use_test_device_conditions_(false), |
204 offliner_(std::move(offliner)), | 221 offliner_(std::move(offliner)), |
205 policy_(std::move(policy)), | 222 policy_(std::move(policy)), |
206 queue_(std::move(queue)), | 223 queue_(std::move(queue)), |
207 scheduler_(std::move(scheduler)), | 224 scheduler_(std::move(scheduler)), |
208 policy_controller_(new ClientPolicyController()), | 225 policy_controller_(new ClientPolicyController()), |
209 network_quality_estimator_(network_quality_estimator), | 226 network_quality_estimator_(network_quality_estimator), |
| 227 network_quality_at_request_start_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
210 active_request_id_(0), | 228 active_request_id_(0), |
211 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), | 229 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), |
212 scheduler_callback_(base::Bind(&EmptySchedulerCallback)), | 230 scheduler_callback_(base::Bind(&EmptySchedulerCallback)), |
213 internal_start_processing_callback_(base::Bind(&EmptySchedulerCallback)), | 231 internal_start_processing_callback_(base::Bind(&EmptySchedulerCallback)), |
214 weak_ptr_factory_(this) { | 232 weak_ptr_factory_(this) { |
215 DCHECK(policy_ != nullptr); | 233 DCHECK(policy_ != nullptr); |
216 std::unique_ptr<CleanupTaskFactory> cleanup_factory( | 234 std::unique_ptr<CleanupTaskFactory> cleanup_factory( |
217 new CleanupTaskFactory(policy_.get(), this, &event_logger_)); | 235 new CleanupTaskFactory(policy_.get(), this, &event_logger_)); |
218 queue_->SetCleanupFactory(std::move(cleanup_factory)); | 236 queue_->SetCleanupFactory(std::move(cleanup_factory)); |
219 // If we exited with any items left in the OFFLINING state, move them back to | 237 // If we exited with any items left in the OFFLINING state, move them back to |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 void RequestCoordinator::RemoveRequests( | 409 void RequestCoordinator::RemoveRequests( |
392 const std::vector<int64_t>& request_ids, | 410 const std::vector<int64_t>& request_ids, |
393 const RemoveRequestsCallback& callback) { | 411 const RemoveRequestsCallback& callback) { |
394 bool canceled = CancelActiveRequestIfItMatches(request_ids); | 412 bool canceled = CancelActiveRequestIfItMatches(request_ids); |
395 queue_->RemoveRequests( | 413 queue_->RemoveRequests( |
396 request_ids, | 414 request_ids, |
397 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback, | 415 base::Bind(&RequestCoordinator::HandleRemovedRequestsAndCallback, |
398 weak_ptr_factory_.GetWeakPtr(), callback, | 416 weak_ptr_factory_.GetWeakPtr(), callback, |
399 RequestNotifier::BackgroundSavePageResult::REMOVED)); | 417 RequestNotifier::BackgroundSavePageResult::REMOVED)); |
400 | 418 |
401 // Record the network quality when this request is made. | 419 // Record the network quality when this request is removed. |
402 if (network_quality_estimator_) { | 420 if (network_quality_estimator_) { |
403 UMA_HISTOGRAM_ENUMERATION( | 421 UMA_HISTOGRAM_ENUMERATION( |
404 "OfflinePages.Background.EffectiveConnectionType.RemoveRequests", | 422 "OfflinePages.Background.EffectiveConnectionType.RemoveRequests", |
405 network_quality_estimator_->GetEffectiveConnectionType(), | 423 network_quality_estimator_->GetEffectiveConnectionType(), |
406 net::EFFECTIVE_CONNECTION_TYPE_LAST); | 424 net::EFFECTIVE_CONNECTION_TYPE_LAST); |
407 } | 425 } |
408 | 426 |
409 if (canceled) | 427 if (canceled) |
410 TryNextRequest(!kStartOfProcessing); | 428 TryNextRequest(!kStartOfProcessing); |
411 } | 429 } |
412 | 430 |
413 void RequestCoordinator::PauseRequests( | 431 void RequestCoordinator::PauseRequests( |
414 const std::vector<int64_t>& request_ids) { | 432 const std::vector<int64_t>& request_ids) { |
415 bool canceled = CancelActiveRequestIfItMatches(request_ids); | 433 bool canceled = CancelActiveRequestIfItMatches(request_ids); |
416 | 434 |
417 // Remove the paused requests from prioritized list. | 435 // Remove the paused requests from prioritized list. |
418 for (int64_t id : request_ids) { | 436 for (int64_t id : request_ids) { |
419 auto it = std::find(prioritized_requests_.begin(), | 437 auto it = std::find(prioritized_requests_.begin(), |
420 prioritized_requests_.end(), id); | 438 prioritized_requests_.end(), id); |
421 if (it != prioritized_requests_.end()) | 439 if (it != prioritized_requests_.end()) |
422 prioritized_requests_.erase(it); | 440 prioritized_requests_.erase(it); |
423 } | 441 } |
424 | 442 |
425 queue_->ChangeRequestsState( | 443 queue_->ChangeRequestsState( |
426 request_ids, SavePageRequest::RequestState::PAUSED, | 444 request_ids, SavePageRequest::RequestState::PAUSED, |
427 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, | 445 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, |
428 weak_ptr_factory_.GetWeakPtr())); | 446 weak_ptr_factory_.GetWeakPtr())); |
429 | 447 |
430 // Record the network quality when this request is made. | 448 // Record the network quality when this request is paused. |
431 if (network_quality_estimator_) { | 449 if (network_quality_estimator_) { |
432 UMA_HISTOGRAM_ENUMERATION( | 450 UMA_HISTOGRAM_ENUMERATION( |
433 "OfflinePages.Background.EffectiveConnectionType.PauseRequests", | 451 "OfflinePages.Background.EffectiveConnectionType.PauseRequests", |
434 network_quality_estimator_->GetEffectiveConnectionType(), | 452 network_quality_estimator_->GetEffectiveConnectionType(), |
435 net::EFFECTIVE_CONNECTION_TYPE_LAST); | 453 net::EFFECTIVE_CONNECTION_TYPE_LAST); |
436 } | 454 } |
437 | 455 |
438 if (canceled) | 456 if (canceled) |
439 TryNextRequest(!kStartOfProcessing); | 457 TryNextRequest(!kStartOfProcessing); |
440 } | 458 } |
441 | 459 |
442 void RequestCoordinator::ResumeRequests( | 460 void RequestCoordinator::ResumeRequests( |
443 const std::vector<int64_t>& request_ids) { | 461 const std::vector<int64_t>& request_ids) { |
444 prioritized_requests_.insert(prioritized_requests_.end(), request_ids.begin(), | 462 prioritized_requests_.insert(prioritized_requests_.end(), request_ids.begin(), |
445 request_ids.end()); | 463 request_ids.end()); |
446 queue_->ChangeRequestsState( | 464 queue_->ChangeRequestsState( |
447 request_ids, SavePageRequest::RequestState::AVAILABLE, | 465 request_ids, SavePageRequest::RequestState::AVAILABLE, |
448 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, | 466 base::Bind(&RequestCoordinator::UpdateMultipleRequestsCallback, |
449 weak_ptr_factory_.GetWeakPtr())); | 467 weak_ptr_factory_.GetWeakPtr())); |
450 | 468 |
451 // Record the network quality when this request is made. | 469 // Record the network quality when this request is resumed. |
452 if (network_quality_estimator_) { | 470 if (network_quality_estimator_) { |
453 UMA_HISTOGRAM_ENUMERATION( | 471 UMA_HISTOGRAM_ENUMERATION( |
454 "OfflinePages.Background.EffectiveConnectionType.ResumeRequests", | 472 "OfflinePages.Background.EffectiveConnectionType.ResumeRequests", |
455 network_quality_estimator_->GetEffectiveConnectionType(), | 473 network_quality_estimator_->GetEffectiveConnectionType(), |
456 net::EFFECTIVE_CONNECTION_TYPE_LAST); | 474 net::EFFECTIVE_CONNECTION_TYPE_LAST); |
457 } | 475 } |
458 | 476 |
459 // Schedule a task, in case there is not one scheduled. | 477 // Schedule a task, in case there is not one scheduled. |
460 ScheduleAsNeeded(); | 478 ScheduleAsNeeded(); |
461 } | 479 } |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 DVLOG(1) << "Failed to mark attempt started: " << request_id; | 887 DVLOG(1) << "Failed to mark attempt started: " << request_id; |
870 UpdateRequestResult request_result = | 888 UpdateRequestResult request_result = |
871 update_result->store_state != StoreState::LOADED | 889 update_result->store_state != StoreState::LOADED |
872 ? UpdateRequestResult::STORE_FAILURE | 890 ? UpdateRequestResult::STORE_FAILURE |
873 : UpdateRequestResult::REQUEST_DOES_NOT_EXIST; | 891 : UpdateRequestResult::REQUEST_DOES_NOT_EXIST; |
874 event_logger_.RecordUpdateRequestFailed(client_namespace, request_result); | 892 event_logger_.RecordUpdateRequestFailed(client_namespace, request_result); |
875 return; | 893 return; |
876 } | 894 } |
877 | 895 |
878 active_request_id_ = request_id; | 896 active_request_id_ = request_id; |
| 897 network_quality_at_request_start_ = |
| 898 network_quality_estimator_->GetEffectiveConnectionType(); |
879 | 899 |
880 // Start the load and save process in the offliner (Async). | 900 // Start the load and save process in the offliner (Async). |
881 if (offliner_->LoadAndSave( | 901 if (offliner_->LoadAndSave( |
882 update_result->updated_items.at(0), | 902 update_result->updated_items.at(0), |
883 base::Bind(&RequestCoordinator::OfflinerDoneCallback, | 903 base::Bind(&RequestCoordinator::OfflinerDoneCallback, |
884 weak_ptr_factory_.GetWeakPtr()), | 904 weak_ptr_factory_.GetWeakPtr()), |
885 base::Bind(&RequestCoordinator::OfflinerProgressCallback, | 905 base::Bind(&RequestCoordinator::OfflinerProgressCallback, |
886 weak_ptr_factory_.GetWeakPtr()))) { | 906 weak_ptr_factory_.GetWeakPtr()))) { |
887 base::TimeDelta timeout; | 907 base::TimeDelta timeout; |
888 if (processing_state_ == ProcessingWindowState::SCHEDULED_WINDOW) { | 908 if (processing_state_ == ProcessingWindowState::SCHEDULED_WINDOW) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 const SavePageRequest& request, | 955 const SavePageRequest& request, |
936 int64_t received_bytes) { | 956 int64_t received_bytes) { |
937 DVLOG(2) << "offliner progress, received bytes: " << received_bytes; | 957 DVLOG(2) << "offliner progress, received bytes: " << received_bytes; |
938 DCHECK(received_bytes >= 0); | 958 DCHECK(received_bytes >= 0); |
939 NotifyNetworkProgress(request, received_bytes); | 959 NotifyNetworkProgress(request, received_bytes); |
940 } | 960 } |
941 | 961 |
942 void RequestCoordinator::UpdateRequestForCompletedAttempt( | 962 void RequestCoordinator::UpdateRequestForCompletedAttempt( |
943 const SavePageRequest& request, | 963 const SavePageRequest& request, |
944 Offliner::RequestStatus status) { | 964 Offliner::RequestStatus status) { |
| 965 // If the request failed, report the connection type as of the start of the |
| 966 // request. |
| 967 if (status != Offliner::RequestStatus::SAVED && |
| 968 status != Offliner::RequestStatus::SAVED_ON_LAST_RETRY) { |
| 969 RecordNetworkQualityAtRequestStartForFailedRequest( |
| 970 request.client_id(), network_quality_at_request_start_); |
| 971 } |
| 972 |
945 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED || | 973 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED || |
946 status == Offliner::RequestStatus::LOADING_CANCELED) { | 974 status == Offliner::RequestStatus::LOADING_CANCELED) { |
947 // Update the request for the canceled attempt. | 975 // Update the request for the canceled attempt. |
948 // TODO(dougarnett): See if we can conclusively identify other attempt | 976 // TODO(dougarnett): See if we can conclusively identify other attempt |
949 // aborted cases to treat this way (eg, for Render Process Killed). | 977 // aborted cases to treat this way (eg, for Render Process Killed). |
950 UpdateRequestForAbortedAttempt(request); | 978 UpdateRequestForAbortedAttempt(request); |
951 } else if (status == Offliner::RequestStatus::SAVED || | 979 } else if (status == Offliner::RequestStatus::SAVED || |
952 status == Offliner::RequestStatus::SAVED_ON_LAST_RETRY) { | 980 status == Offliner::RequestStatus::SAVED_ON_LAST_RETRY) { |
953 // Remove the request from the queue if it succeeded. | 981 // Remove the request from the queue if it succeeded. |
954 RemoveAttemptedRequest(request, | 982 RemoveAttemptedRequest(request, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 event_logger_.RecordOfflinerResult(request.client_id().name_space, status, | 1119 event_logger_.RecordOfflinerResult(request.client_id().name_space, status, |
1092 request.request_id()); | 1120 request.request_id()); |
1093 RecordOfflinerResultUMA(request.client_id(), request.creation_time(), status); | 1121 RecordOfflinerResultUMA(request.client_id(), request.creation_time(), status); |
1094 } | 1122 } |
1095 | 1123 |
1096 void RequestCoordinator::Shutdown() { | 1124 void RequestCoordinator::Shutdown() { |
1097 network_quality_estimator_ = nullptr; | 1125 network_quality_estimator_ = nullptr; |
1098 } | 1126 } |
1099 | 1127 |
1100 } // namespace offline_pages | 1128 } // namespace offline_pages |
OLD | NEW |