Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: chrome/browser/android/offline_pages/background_loader_offliner.cc

Issue 2714733003: [Offline Pages] Add a timer to BackgroundLoaderOffliner to delay SavePage by 2 seconds. (Closed)
Patch Set: fix tests and last comment Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/android/offline_pages/background_loader_offliner.h" 5 #include "chrome/browser/android/offline_pages/background_loader_offliner.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "base/sys_info.h" 8 #include "base/sys_info.h"
9 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h" 9 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
10 #include "chrome/browser/android/offline_pages/offliner_helper.h" 10 #include "chrome/browser/android/offline_pages/offliner_helper.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "components/offline_pages/core/background/save_page_request.h" 12 #include "components/offline_pages/core/background/save_page_request.h"
13 #include "components/offline_pages/core/client_namespace_constants.h" 13 #include "components/offline_pages/core/client_namespace_constants.h"
14 #include "components/offline_pages/core/offline_page_model.h" 14 #include "components/offline_pages/core/offline_page_model.h"
15 #include "content/public/browser/browser_context.h" 15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/navigation_handle.h" 16 #include "content/public/browser/navigation_handle.h"
17 #include "content/public/browser/web_contents.h" 17 #include "content/public/browser/web_contents.h"
18 18
19 namespace offline_pages { 19 namespace offline_pages {
20 20
21 namespace {
22 long kOfflinePageDelayMs = 2000;
23 } // namespace
24
21 BackgroundLoaderOffliner::BackgroundLoaderOffliner( 25 BackgroundLoaderOffliner::BackgroundLoaderOffliner(
22 content::BrowserContext* browser_context, 26 content::BrowserContext* browser_context,
23 const OfflinerPolicy* policy, 27 const OfflinerPolicy* policy,
24 OfflinePageModel* offline_page_model) 28 OfflinePageModel* offline_page_model)
25 : browser_context_(browser_context), 29 : browser_context_(browser_context),
26 offline_page_model_(offline_page_model), 30 offline_page_model_(offline_page_model),
27 is_low_end_device_(base::SysInfo::IsLowEndDevice()), 31 is_low_end_device_(base::SysInfo::IsLowEndDevice()),
28 save_state_(NONE), 32 save_state_(NONE),
29 page_load_state_(SUCCESS), 33 page_load_state_(SUCCESS),
34 page_delay_ms_(kOfflinePageDelayMs),
30 weak_ptr_factory_(this) { 35 weak_ptr_factory_(this) {
31 DCHECK(offline_page_model_); 36 DCHECK(offline_page_model_);
32 DCHECK(browser_context_); 37 DCHECK(browser_context_);
33 } 38 }
34 39
35 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {} 40 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {}
36 41
37 bool BackgroundLoaderOffliner::LoadAndSave(const SavePageRequest& request, 42 bool BackgroundLoaderOffliner::LoadAndSave(const SavePageRequest& request,
38 const CompletionCallback& callback) { 43 const CompletionCallback& callback) {
39 DCHECK(callback); 44 DCHECK(callback);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 } 92 }
88 93
89 if (!OfflinePageModel::CanSaveURL(request.url())) { 94 if (!OfflinePageModel::CanSaveURL(request.url())) {
90 DVLOG(1) << "Not able to save page for requested url: " << request.url(); 95 DVLOG(1) << "Not able to save page for requested url: " << request.url();
91 return false; 96 return false;
92 } 97 }
93 98
94 if (!loader_) 99 if (!loader_)
95 ResetState(); 100 ResetState();
96 101
102 // Invalidate ptrs for all delayed/saving tasks.
103 weak_ptr_factory_.InvalidateWeakPtrs();
104
97 // Track copy of pending request. 105 // Track copy of pending request.
98 pending_request_.reset(new SavePageRequest(request)); 106 pending_request_.reset(new SavePageRequest(request));
99 completion_callback_ = callback; 107 completion_callback_ = callback;
100 108
101 // Listen for app foreground/background change. 109 // Listen for app foreground/background change.
102 app_listener_.reset(new base::android::ApplicationStatusListener( 110 app_listener_.reset(new base::android::ApplicationStatusListener(
103 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange, 111 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange,
104 weak_ptr_factory_.GetWeakPtr()))); 112 weak_ptr_factory_.GetWeakPtr())));
105 113
106 // Load page attempt. 114 // Load page attempt.
(...skipping 15 matching lines...) Expand all
122 130
123 ResetState(); 131 ResetState();
124 } 132 }
125 133
126 void BackgroundLoaderOffliner::DidStopLoading() { 134 void BackgroundLoaderOffliner::DidStopLoading() {
127 if (!pending_request_.get()) { 135 if (!pending_request_.get()) {
128 DVLOG(1) << "DidStopLoading called even though no pending request."; 136 DVLOG(1) << "DidStopLoading called even though no pending request.";
129 return; 137 return;
130 } 138 }
131 139
132 SavePageRequest request(*pending_request_.get()); 140 // Invalidate ptrs for any ongoing save operation.
133 // If there was an error navigating to page, return loading failed. 141 weak_ptr_factory_.InvalidateWeakPtrs();
134 if (page_load_state_ != SUCCESS) {
135 Offliner::RequestStatus status =
136 (page_load_state_ == RETRIABLE)
137 ? Offliner::RequestStatus::LOADING_FAILED
138 : Offliner::RequestStatus::LOADING_FAILED_NO_RETRY;
139 completion_callback_.Run(request, status);
140 ResetState();
141 return;
142 }
143 142
144 save_state_ = SAVING; 143 // Post SavePage task with 2 second delay.
145 content::WebContents* web_contents( 144 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
146 content::WebContentsObserver::web_contents()); 145 FROM_HERE,
147 146 base::Bind(&BackgroundLoaderOffliner::SavePage,
148 std::unique_ptr<OfflinePageArchiver> archiver( 147 weak_ptr_factory_.GetWeakPtr()),
149 new OfflinePageMHTMLArchiver(web_contents)); 148 base::TimeDelta::FromMilliseconds(page_delay_ms_));
150
151 OfflinePageModel::SavePageParams params;
152 params.url = web_contents->GetLastCommittedURL();
153 params.client_id = request.client_id();
154 params.proposed_offline_id = request.request_id();
155 params.is_background = true;
156
157 // Pass in the original URL if it's different from last committed
158 // when redirects occur.
159 if (params.url != request.url())
160 params.original_url = request.url();
161
162 offline_page_model_->SavePage(
163 params, std::move(archiver),
164 base::Bind(&BackgroundLoaderOffliner::OnPageSaved,
165 weak_ptr_factory_.GetWeakPtr()));
166 } 149 }
167 150
168 void BackgroundLoaderOffliner::RenderProcessGone( 151 void BackgroundLoaderOffliner::RenderProcessGone(
169 base::TerminationStatus status) { 152 base::TerminationStatus status) {
170 if (pending_request_) { 153 if (pending_request_) {
171 SavePageRequest request(*pending_request_.get()); 154 SavePageRequest request(*pending_request_.get());
172 switch (status) { 155 switch (status) {
173 case base::TERMINATION_STATUS_OOM: 156 case base::TERMINATION_STATUS_OOM:
174 case base::TERMINATION_STATUS_PROCESS_CRASHED: 157 case base::TERMINATION_STATUS_PROCESS_CRASHED:
175 case base::TERMINATION_STATUS_STILL_RUNNING: 158 case base::TERMINATION_STATUS_STILL_RUNNING:
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 case net::ERR_SSL_PROTOCOL_ERROR: 206 case net::ERR_SSL_PROTOCOL_ERROR:
224 case net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED: 207 case net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED:
225 case net::ERR_SSL_SERVER_CERT_BAD_FORMAT: 208 case net::ERR_SSL_SERVER_CERT_BAD_FORMAT:
226 case net::ERR_UNKNOWN_URL_SCHEME: 209 case net::ERR_UNKNOWN_URL_SCHEME:
227 page_load_state_ = NONRETRIABLE; 210 page_load_state_ = NONRETRIABLE;
228 break; 211 break;
229 default: 212 default:
230 page_load_state_ = RETRIABLE; 213 page_load_state_ = RETRIABLE;
231 } 214 }
232 } 215 }
216
217 // If the page is not the same, invalidate any pending save tasks.
218 //
219 // Downloads or 204/205 response codes do not commit (no new navigation)
220 // Same-Page (committed) navigations are:
221 // - reference fragment navigations
222 // - pushState/replaceState
223 // - same page history navigation
224 if (navigation_handle->HasCommitted() && !navigation_handle->IsSamePage())
225 weak_ptr_factory_.InvalidateWeakPtrs();
226 }
227
228 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) {
229 page_delay_ms_ = delay_ms;
230 }
231
232 void BackgroundLoaderOffliner::SavePage() {
233 if (!pending_request_.get()) {
234 DVLOG(1) << "Pending request was cleared during delay.";
235 return;
236 }
237
238 SavePageRequest request(*pending_request_.get());
239 // If there was an error navigating to page, return loading failed.
240 if (page_load_state_ != SUCCESS) {
241 Offliner::RequestStatus status =
242 (page_load_state_ == RETRIABLE)
243 ? Offliner::RequestStatus::LOADING_FAILED
244 : Offliner::RequestStatus::LOADING_FAILED_NO_RETRY;
245 completion_callback_.Run(request, status);
246 ResetState();
247 return;
248 }
249
250 save_state_ = SAVING;
251 content::WebContents* web_contents(
252 content::WebContentsObserver::web_contents());
253
254 std::unique_ptr<OfflinePageArchiver> archiver(
255 new OfflinePageMHTMLArchiver(web_contents));
256
257 OfflinePageModel::SavePageParams params;
258 params.url = web_contents->GetLastCommittedURL();
259 params.client_id = request.client_id();
260 params.proposed_offline_id = request.request_id();
261 params.is_background = true;
262
263 // Pass in the original URL if it's different from last committed
264 // when redirects occur.
265 if (params.url != request.url())
266 params.original_url = request.url();
267
268 offline_page_model_->SavePage(
269 params, std::move(archiver),
270 base::Bind(&BackgroundLoaderOffliner::OnPageSaved,
271 weak_ptr_factory_.GetWeakPtr()));
233 } 272 }
234 273
235 void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result, 274 void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result,
236 int64_t offline_id) { 275 int64_t offline_id) {
237 if (!pending_request_) 276 if (!pending_request_)
238 return; 277 return;
239 278
240 SavePageRequest request(*pending_request_.get()); 279 SavePageRequest request(*pending_request_.get());
241 ResetState(); 280 ResetState();
242 281
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 application_state == 314 application_state ==
276 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { 315 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
277 DVLOG(1) << "App became active, canceling current offlining request"; 316 DVLOG(1) << "App became active, canceling current offlining request";
278 SavePageRequest* request = pending_request_.get(); 317 SavePageRequest* request = pending_request_.get();
279 Cancel(); 318 Cancel();
280 completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED); 319 completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED);
281 } 320 }
282 } 321 }
283 322
284 } // namespace offline_pages 323 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698