| 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 "chrome/browser/offline_pages/background_loader_offliner.h" | 5 #include "chrome/browser/offline_pages/background_loader_offliner.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/sys_info.h" | 10 #include "base/sys_info.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 return adjusted_histogram_name; | 66 return adjusted_histogram_name; |
| 67 } | 67 } |
| 68 | 68 |
| 69 void RecordErrorCauseUMA(const ClientId& client_id, net::Error error_code) { | 69 void RecordErrorCauseUMA(const ClientId& client_id, net::Error error_code) { |
| 70 UMA_HISTOGRAM_SPARSE_SLOWLY( | 70 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 71 AddHistogramSuffix(client_id, | 71 AddHistogramSuffix(client_id, |
| 72 "OfflinePages.Background.BackgroundLoadingFailedCode"), | 72 "OfflinePages.Background.BackgroundLoadingFailedCode"), |
| 73 std::abs(error_code)); | 73 std::abs(error_code)); |
| 74 } | 74 } |
| 75 | 75 |
| 76 void HandleApplicationStateChangeCancel( | 76 void HandleLoadTerminationCancel( |
| 77 const Offliner::CompletionCallback& completion_callback, | 77 const Offliner::CompletionCallback& completion_callback, |
| 78 const SavePageRequest& canceled_request) { | 78 const SavePageRequest& canceled_request) { |
| 79 completion_callback.Run(canceled_request, | 79 completion_callback.Run(canceled_request, |
| 80 Offliner::RequestStatus::FOREGROUND_CANCELED); | 80 Offliner::RequestStatus::FOREGROUND_CANCELED); |
| 81 } | 81 } |
| 82 | 82 |
| 83 } // namespace | 83 } // namespace |
| 84 | 84 |
| 85 BackgroundLoaderOffliner::BackgroundLoaderOffliner( | 85 BackgroundLoaderOffliner::BackgroundLoaderOffliner( |
| 86 content::BrowserContext* browser_context, | 86 content::BrowserContext* browser_context, |
| 87 const OfflinerPolicy* policy, | 87 const OfflinerPolicy* policy, |
| 88 OfflinePageModel* offline_page_model) | 88 OfflinePageModel* offline_page_model, |
| 89 std::unique_ptr<LoadTerminationListener> load_termination_listener) |
| 89 : browser_context_(browser_context), | 90 : browser_context_(browser_context), |
| 90 offline_page_model_(offline_page_model), | 91 offline_page_model_(offline_page_model), |
| 91 policy_(policy), | 92 policy_(policy), |
| 92 is_low_end_device_(base::SysInfo::IsLowEndDevice()), | 93 load_termination_listener_(std::move(load_termination_listener)), |
| 93 save_state_(NONE), | 94 save_state_(NONE), |
| 94 page_load_state_(SUCCESS), | 95 page_load_state_(SUCCESS), |
| 95 network_bytes_(0LL), | 96 network_bytes_(0LL), |
| 96 is_low_bar_met_(false), | 97 is_low_bar_met_(false), |
| 97 did_snapshot_on_last_retry_(false), | 98 did_snapshot_on_last_retry_(false), |
| 98 weak_ptr_factory_(this) { | 99 weak_ptr_factory_(this) { |
| 99 DCHECK(offline_page_model_); | 100 DCHECK(offline_page_model_); |
| 100 DCHECK(browser_context_); | 101 DCHECK(browser_context_); |
| 102 load_termination_listener_->set_offliner(this); |
| 101 } | 103 } |
| 102 | 104 |
| 103 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {} | 105 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {} |
| 104 | 106 |
| 105 // static | 107 // static |
| 106 BackgroundLoaderOffliner* BackgroundLoaderOffliner::FromWebContents( | 108 BackgroundLoaderOffliner* BackgroundLoaderOffliner::FromWebContents( |
| 107 content::WebContents* contents) { | 109 content::WebContents* contents) { |
| 108 OfflinerData* data = OfflinerData::FromWebContents(contents); | 110 OfflinerData* data = OfflinerData::FromWebContents(contents); |
| 109 if (data) | 111 if (data) |
| 110 return data->offliner(); | 112 return data->offliner(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 ResetLoader(); | 177 ResetLoader(); |
| 176 AttachObservers(); | 178 AttachObservers(); |
| 177 | 179 |
| 178 MarkLoadStartTime(); | 180 MarkLoadStartTime(); |
| 179 | 181 |
| 180 // Track copy of pending request. | 182 // Track copy of pending request. |
| 181 pending_request_.reset(new SavePageRequest(request)); | 183 pending_request_.reset(new SavePageRequest(request)); |
| 182 completion_callback_ = completion_callback; | 184 completion_callback_ = completion_callback; |
| 183 progress_callback_ = progress_callback; | 185 progress_callback_ = progress_callback; |
| 184 | 186 |
| 185 // Listen for app foreground/background change. | |
| 186 app_listener_.reset(new base::android::ApplicationStatusListener( | |
| 187 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange, | |
| 188 weak_ptr_factory_.GetWeakPtr()))); | |
| 189 | |
| 190 // Load page attempt. | 187 // Load page attempt. |
| 191 loader_.get()->LoadPage(request.url()); | 188 loader_.get()->LoadPage(request.url()); |
| 192 | 189 |
| 193 snapshot_controller_ = SnapshotController::CreateForBackgroundOfflining( | 190 snapshot_controller_ = SnapshotController::CreateForBackgroundOfflining( |
| 194 base::ThreadTaskRunnerHandle::Get(), this); | 191 base::ThreadTaskRunnerHandle::Get(), this); |
| 195 | 192 |
| 196 return true; | 193 return true; |
| 197 } | 194 } |
| 198 | 195 |
| 199 bool BackgroundLoaderOffliner::Cancel(const CancelCallback& callback) { | 196 bool BackgroundLoaderOffliner::Cancel(const CancelCallback& callback) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 212 return true; | 209 return true; |
| 213 } | 210 } |
| 214 | 211 |
| 215 // Post the cancel callback right after this call concludes. | 212 // Post the cancel callback right after this call concludes. |
| 216 base::ThreadTaskRunnerHandle::Get()->PostTask( | 213 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 217 FROM_HERE, base::Bind(callback, *pending_request_.get())); | 214 FROM_HERE, base::Bind(callback, *pending_request_.get())); |
| 218 ResetState(); | 215 ResetState(); |
| 219 return true; | 216 return true; |
| 220 } | 217 } |
| 221 | 218 |
| 219 void BackgroundLoaderOffliner::TerminateLoadIfInProgress() { |
| 220 if (!pending_request_) |
| 221 return; |
| 222 |
| 223 Cancel(base::Bind(HandleLoadTerminationCancel, completion_callback_)); |
| 224 } |
| 225 |
| 222 bool BackgroundLoaderOffliner::HandleTimeout(int64_t request_id) { | 226 bool BackgroundLoaderOffliner::HandleTimeout(int64_t request_id) { |
| 223 if (pending_request_) { | 227 if (pending_request_) { |
| 224 DCHECK(request_id == pending_request_->request_id()); | 228 DCHECK(request_id == pending_request_->request_id()); |
| 225 if (is_low_bar_met_ && (pending_request_->started_attempt_count() + 1 >= | 229 if (is_low_bar_met_ && (pending_request_->started_attempt_count() + 1 >= |
| 226 policy_->GetMaxStartedTries() || | 230 policy_->GetMaxStartedTries() || |
| 227 pending_request_->completed_attempt_count() + 1 >= | 231 pending_request_->completed_attempt_count() + 1 >= |
| 228 policy_->GetMaxCompletedTries())) { | 232 policy_->GetMaxCompletedTries())) { |
| 229 // If we are already in the middle of a save operation, let it finish | 233 // If we are already in the middle of a save operation, let it finish |
| 230 // but do not return SAVED_ON_LAST_RETRY | 234 // but do not return SAVED_ON_LAST_RETRY |
| 231 if (save_state_ == NONE) { | 235 if (save_state_ == NONE) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 loader_.reset( | 466 loader_.reset( |
| 463 new background_loader::BackgroundLoaderContents(browser_context_)); | 467 new background_loader::BackgroundLoaderContents(browser_context_)); |
| 464 } | 468 } |
| 465 | 469 |
| 466 void BackgroundLoaderOffliner::AttachObservers() { | 470 void BackgroundLoaderOffliner::AttachObservers() { |
| 467 content::WebContents* contents = loader_->web_contents(); | 471 content::WebContents* contents = loader_->web_contents(); |
| 468 content::WebContentsObserver::Observe(contents); | 472 content::WebContentsObserver::Observe(contents); |
| 469 OfflinerData::AddToWebContents(contents, this); | 473 OfflinerData::AddToWebContents(contents, this); |
| 470 } | 474 } |
| 471 | 475 |
| 472 void BackgroundLoaderOffliner::OnApplicationStateChange( | |
| 473 base::android::ApplicationState application_state) { | |
| 474 if (pending_request_ && is_low_end_device_ && | |
| 475 application_state == | |
| 476 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { | |
| 477 DVLOG(1) << "App became active, canceling current offlining request"; | |
| 478 // No need to check the return value or complete early, as false would | |
| 479 // indicate that there was no request, in which case the state change is | |
| 480 // ignored. | |
| 481 Cancel( | |
| 482 base::Bind(HandleApplicationStateChangeCancel, completion_callback_)); | |
| 483 } | |
| 484 } | |
| 485 | |
| 486 void BackgroundLoaderOffliner::AddLoadingSignal(const char* signal_name) { | 476 void BackgroundLoaderOffliner::AddLoadingSignal(const char* signal_name) { |
| 487 base::TimeTicks current_time = base::TimeTicks::Now(); | 477 base::TimeTicks current_time = base::TimeTicks::Now(); |
| 488 base::TimeDelta delay_so_far = current_time - load_start_time_; | 478 base::TimeDelta delay_so_far = current_time - load_start_time_; |
| 489 // We would prefer to use int64_t here, but JSON does not support that type. | 479 // We would prefer to use int64_t here, but JSON does not support that type. |
| 490 // Given the choice between int and double, we choose to implicitly convert to | 480 // Given the choice between int and double, we choose to implicitly convert to |
| 491 // a double since it maintains more precision (we can get a longer time in | 481 // a double since it maintains more precision (we can get a longer time in |
| 492 // milliseconds than we can with a 2 bit int, 53 bits vs 32). | 482 // milliseconds than we can with a 2 bit int, 53 bits vs 32). |
| 493 double delay = delay_so_far.InMilliseconds(); | 483 double delay = delay_so_far.InMilliseconds(); |
| 494 signal_data_.SetDouble(signal_name, delay); | 484 signal_data_.SetDouble(signal_name, delay); |
| 495 } | 485 } |
| 496 | 486 |
| 497 } // namespace offline_pages | 487 } // namespace offline_pages |
| 498 | 488 |
| 499 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData); | 489 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData); |
| OLD | NEW |