| 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/time/time.h" | 13 #include "base/time/time.h" |
| 14 #include "components/offline_pages/background/offliner_factory.h" | 14 #include "components/offline_pages/background/offliner_factory.h" |
| 15 #include "components/offline_pages/background/offliner_policy.h" | 15 #include "components/offline_pages/background/offliner_policy.h" |
| 16 #include "components/offline_pages/background/request_picker.h" | 16 #include "components/offline_pages/background/request_picker.h" |
| 17 #include "components/offline_pages/background/save_page_request.h" | 17 #include "components/offline_pages/background/save_page_request.h" |
| 18 #include "components/offline_pages/offline_page_item.h" | 18 #include "components/offline_pages/offline_page_item.h" |
| 19 #include "components/offline_pages/offline_page_model.h" | 19 #include "components/offline_pages/offline_page_model.h" |
| 20 | 20 |
| 21 namespace offline_pages { | 21 namespace offline_pages { |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // Records the final request status UMA for an offlining request. This should | 25 // Records the final request status UMA for an offlining request. This should |
| 26 // only be called once per Offliner::LoadAndSave request. | 26 // only be called once per Offliner::LoadAndSave request. |
| 27 void RecordOfflinerResultUMA(Offliner::RequestStatus request_status) { | 27 void RecordOfflinerResultUMA(const ClientId& client_id, |
| 28 UMA_HISTOGRAM_ENUMERATION("OfflinePages.Background.OfflinerRequestStatus", | 28 Offliner::RequestStatus request_status) { |
| 29 request_status, | 29 // TODO(dougarnett): Consider exposing AddHistogramSuffix from |
| 30 Offliner::RequestStatus::STATUS_COUNT); | 30 // offline_page_model_impl.cc as visible utility method. |
| 31 std::string histogram_name("OfflinePages.Background.OfflinerRequestStatus"); |
| 32 if (!client_id.name_space.empty()) { |
| 33 histogram_name += "." + client_id.name_space; |
| 34 } |
| 35 |
| 36 // The histogram below is an expansion of the UMA_HISTOGRAM_ENUMERATION |
| 37 // macro adapted to allow for a dynamically suffixed histogram name. |
| 38 // Note: The factory creates and owns the histogram. |
| 39 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
| 40 histogram_name, 1, |
| 41 static_cast<int>(Offliner::RequestStatus::STATUS_COUNT), |
| 42 static_cast<int>(Offliner::RequestStatus::STATUS_COUNT) + 1, |
| 43 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 44 histogram->Add(static_cast<int>(request_status)); |
| 31 } | 45 } |
| 32 | 46 |
| 33 } // namespace | 47 } // namespace |
| 34 | 48 |
| 35 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy, | 49 RequestCoordinator::RequestCoordinator(std::unique_ptr<OfflinerPolicy> policy, |
| 36 std::unique_ptr<OfflinerFactory> factory, | 50 std::unique_ptr<OfflinerFactory> factory, |
| 37 std::unique_ptr<RequestQueue> queue, | 51 std::unique_ptr<RequestQueue> queue, |
| 38 std::unique_ptr<Scheduler> scheduler) | 52 std::unique_ptr<Scheduler> scheduler) |
| 39 : is_busy_(false), | 53 : is_busy_(false), |
| 40 is_canceled_(false), | 54 is_canceled_(false), |
| 41 offliner_(nullptr), | 55 offliner_(nullptr), |
| 42 policy_(std::move(policy)), | 56 policy_(std::move(policy)), |
| 43 factory_(std::move(factory)), | 57 factory_(std::move(factory)), |
| 44 queue_(std::move(queue)), | 58 queue_(std::move(queue)), |
| 45 scheduler_(std::move(scheduler)), | 59 scheduler_(std::move(scheduler)), |
| 60 active_request_(nullptr), |
| 46 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), | 61 last_offlining_status_(Offliner::RequestStatus::UNKNOWN), |
| 47 offliner_timeout_(base::TimeDelta::FromSeconds( | 62 offliner_timeout_(base::TimeDelta::FromSeconds( |
| 48 policy_->GetSinglePageTimeLimitInSeconds())), | 63 policy_->GetSinglePageTimeLimitInSeconds())), |
| 49 weak_ptr_factory_(this) { | 64 weak_ptr_factory_(this) { |
| 50 DCHECK(policy_ != nullptr); | 65 DCHECK(policy_ != nullptr); |
| 51 picker_.reset(new RequestPicker(queue_.get(), policy_.get())); | 66 picker_.reset(new RequestPicker(queue_.get(), policy_.get())); |
| 52 } | 67 } |
| 53 | 68 |
| 54 RequestCoordinator::~RequestCoordinator() {} | 69 RequestCoordinator::~RequestCoordinator() {} |
| 55 | 70 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 void RequestCoordinator::StopProcessing() { | 159 void RequestCoordinator::StopProcessing() { |
| 145 is_canceled_ = true; | 160 is_canceled_ = true; |
| 146 if (offliner_ && is_busy_) { | 161 if (offliner_ && is_busy_) { |
| 147 // TODO(dougarnett): Find current request and mark attempt aborted. | 162 // TODO(dougarnett): Find current request and mark attempt aborted. |
| 148 offliner_->Cancel(); | 163 offliner_->Cancel(); |
| 149 } | 164 } |
| 150 | 165 |
| 151 // Stopping offliner means it will not call callback. | 166 // Stopping offliner means it will not call callback. |
| 152 last_offlining_status_ = | 167 last_offlining_status_ = |
| 153 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; | 168 Offliner::RequestStatus::REQUEST_COORDINATOR_CANCELED; |
| 154 RecordOfflinerResultUMA(last_offlining_status_); | 169 |
| 170 if (active_request_) { |
| 171 RecordOfflinerResultUMA(active_request_->client_id(), |
| 172 last_offlining_status_); |
| 173 active_request_.reset(); |
| 174 } |
| 155 | 175 |
| 156 // Let the scheduler know we are done processing. | 176 // Let the scheduler know we are done processing. |
| 157 scheduler_callback_.Run(true); | 177 scheduler_callback_.Run(true); |
| 158 } | 178 } |
| 159 | 179 |
| 160 // Returns true if the caller should expect a callback, false otherwise. For | 180 // Returns true if the caller should expect a callback, false otherwise. For |
| 161 // instance, this would return false if a request is already in progress. | 181 // instance, this would return false if a request is already in progress. |
| 162 bool RequestCoordinator::StartProcessing( | 182 bool RequestCoordinator::StartProcessing( |
| 163 const DeviceConditions& device_conditions, | 183 const DeviceConditions& device_conditions, |
| 164 const base::Callback<void(bool)>& callback) { | 184 const base::Callback<void(bool)>& callback) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 | 242 |
| 223 GetOffliner(); | 243 GetOffliner(); |
| 224 if (!offliner_) { | 244 if (!offliner_) { |
| 225 DVLOG(0) << "Unable to create Offliner. " | 245 DVLOG(0) << "Unable to create Offliner. " |
| 226 << "Cannot background offline page."; | 246 << "Cannot background offline page."; |
| 227 return; | 247 return; |
| 228 } | 248 } |
| 229 | 249 |
| 230 DCHECK(!is_busy_); | 250 DCHECK(!is_busy_); |
| 231 is_busy_ = true; | 251 is_busy_ = true; |
| 252 active_request_.reset(new SavePageRequest(request)); |
| 232 | 253 |
| 233 // Prepare an updated request to attempt. | 254 // Prepare an updated request to attempt. |
| 234 SavePageRequest updated_request(request); | 255 SavePageRequest updated_request(request); |
| 235 updated_request.MarkAttemptStarted(base::Time::Now()); | 256 updated_request.MarkAttemptStarted(base::Time::Now()); |
| 236 | 257 |
| 237 // Start the load and save process in the offliner (Async). | 258 // Start the load and save process in the offliner (Async). |
| 238 if (offliner_->LoadAndSave( | 259 if (offliner_->LoadAndSave( |
| 239 updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback, | 260 updated_request, base::Bind(&RequestCoordinator::OfflinerDoneCallback, |
| 240 weak_ptr_factory_.GetWeakPtr()))) { | 261 weak_ptr_factory_.GetWeakPtr()))) { |
| 241 // Offliner accepted request so update it in the queue. | 262 // Offliner accepted request so update it in the queue. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 257 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request, | 278 void RequestCoordinator::OfflinerDoneCallback(const SavePageRequest& request, |
| 258 Offliner::RequestStatus status) { | 279 Offliner::RequestStatus status) { |
| 259 DVLOG(2) << "offliner finished, saved: " | 280 DVLOG(2) << "offliner finished, saved: " |
| 260 << (status == Offliner::RequestStatus::SAVED) | 281 << (status == Offliner::RequestStatus::SAVED) |
| 261 << ", status: " << static_cast<int>(status) << ", " << __func__; | 282 << ", status: " << static_cast<int>(status) << ", " << __func__; |
| 262 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); | 283 DCHECK_NE(status, Offliner::RequestStatus::UNKNOWN); |
| 263 DCHECK_NE(status, Offliner::RequestStatus::LOADED); | 284 DCHECK_NE(status, Offliner::RequestStatus::LOADED); |
| 264 event_logger_.RecordSavePageRequestUpdated(request.client_id().name_space, | 285 event_logger_.RecordSavePageRequestUpdated(request.client_id().name_space, |
| 265 status, request.request_id()); | 286 status, request.request_id()); |
| 266 last_offlining_status_ = status; | 287 last_offlining_status_ = status; |
| 267 RecordOfflinerResultUMA(last_offlining_status_); | 288 RecordOfflinerResultUMA(request.client_id(), last_offlining_status_); |
| 268 watchdog_timer_.Stop(); | 289 watchdog_timer_.Stop(); |
| 269 | 290 |
| 270 is_busy_ = false; | 291 is_busy_ = false; |
| 292 active_request_.reset(nullptr); |
| 271 | 293 |
| 272 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { | 294 if (status == Offliner::RequestStatus::FOREGROUND_CANCELED) { |
| 273 // Update the request for the canceled attempt. | 295 // Update the request for the canceled attempt. |
| 274 // TODO(dougarnett): See if we can conclusively identify other attempt | 296 // TODO(dougarnett): See if we can conclusively identify other attempt |
| 275 // aborted cases to treat this way (eg, for Render Process Killed). | 297 // aborted cases to treat this way (eg, for Render Process Killed). |
| 276 SavePageRequest updated_request(request); | 298 SavePageRequest updated_request(request); |
| 277 updated_request.MarkAttemptAborted(); | 299 updated_request.MarkAttemptAborted(); |
| 278 queue_->UpdateRequest(updated_request, | 300 queue_->UpdateRequest(updated_request, |
| 279 base::Bind(&RequestCoordinator::UpdateRequestCallback, | 301 base::Bind(&RequestCoordinator::UpdateRequestCallback, |
| 280 weak_ptr_factory_.GetWeakPtr(), | 302 weak_ptr_factory_.GetWeakPtr(), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 return trigger_conditions; | 354 return trigger_conditions; |
| 333 } | 355 } |
| 334 | 356 |
| 335 void RequestCoordinator::GetOffliner() { | 357 void RequestCoordinator::GetOffliner() { |
| 336 if (!offliner_) { | 358 if (!offliner_) { |
| 337 offliner_ = factory_->GetOffliner(policy_.get()); | 359 offliner_ = factory_->GetOffliner(policy_.get()); |
| 338 } | 360 } |
| 339 } | 361 } |
| 340 | 362 |
| 341 } // namespace offline_pages | 363 } // namespace offline_pages |
| OLD | NEW |