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

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

Issue 2769043002: [Offline pages] Integrate snapshot controller fully into background loader. (Closed)
Patch Set: added comment and reset 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
« no previous file with comments | « chrome/browser/android/offline_pages/background_loader_offliner.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/render_frame_host.h"
17 #include "content/public/browser/web_contents.h" 18 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_user_data.h" 19 #include "content/public/browser/web_contents_user_data.h"
19 20
20 namespace offline_pages { 21 namespace offline_pages {
21 22
22 namespace { 23 namespace {
23 const long kOfflinePageDelayMs = 2000; 24 const long kOfflinePageDelayMs = 2000;
25 const long kOfflineDomContentLoadedMs = 25000;
24 26
25 class OfflinerData : public content::WebContentsUserData<OfflinerData> { 27 class OfflinerData : public content::WebContentsUserData<OfflinerData> {
26 public: 28 public:
27 static void AddToWebContents(content::WebContents* webcontents, 29 static void AddToWebContents(content::WebContents* webcontents,
28 BackgroundLoaderOffliner* offliner) { 30 BackgroundLoaderOffliner* offliner) {
29 DCHECK(offliner); 31 DCHECK(offliner);
30 webcontents->SetUserData(UserDataKey(), std::unique_ptr<OfflinerData>( 32 webcontents->SetUserData(UserDataKey(), std::unique_ptr<OfflinerData>(
31 new OfflinerData(offliner))); 33 new OfflinerData(offliner)));
32 } 34 }
33 35
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 } 148 }
147 149
148 if (!OfflinePageModel::CanSaveURL(request.url())) { 150 if (!OfflinePageModel::CanSaveURL(request.url())) {
149 DVLOG(1) << "Not able to save page for requested url: " << request.url(); 151 DVLOG(1) << "Not able to save page for requested url: " << request.url();
150 return false; 152 return false;
151 } 153 }
152 154
153 if (!loader_) 155 if (!loader_)
154 ResetState(); 156 ResetState();
155 157
156 // Invalidate ptrs for all delayed/saving tasks.
157 weak_ptr_factory_.InvalidateWeakPtrs();
158
159 // Track copy of pending request. 158 // Track copy of pending request.
160 pending_request_.reset(new SavePageRequest(request)); 159 pending_request_.reset(new SavePageRequest(request));
161 completion_callback_ = completion_callback; 160 completion_callback_ = completion_callback;
162 progress_callback_ = progress_callback; 161 progress_callback_ = progress_callback;
163 162
164 // Listen for app foreground/background change. 163 // Listen for app foreground/background change.
165 app_listener_.reset(new base::android::ApplicationStatusListener( 164 app_listener_.reset(new base::android::ApplicationStatusListener(
166 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange, 165 base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange,
167 weak_ptr_factory_.GetWeakPtr()))); 166 weak_ptr_factory_.GetWeakPtr())));
168 167
169 // Load page attempt. 168 // Load page attempt.
170 loader_.get()->LoadPage(request.url()); 169 loader_.get()->LoadPage(request.url());
171 170
171 snapshot_controller_.reset(
172 new SnapshotController(base::ThreadTaskRunnerHandle::Get(), this,
173 kOfflineDomContentLoadedMs, page_delay_ms_));
174
172 return true; 175 return true;
173 } 176 }
174 177
175 void BackgroundLoaderOffliner::Cancel(const CancelCallback& callback) { 178 void BackgroundLoaderOffliner::Cancel(const CancelCallback& callback) {
176 // TODO(chili): We are not able to cancel a pending 179 // TODO(chili): We are not able to cancel a pending
177 // OfflinePageModel::SavePage() operation. We will notify caller that 180 // OfflinePageModel::SaveSnapshot() operation. We will notify caller that
178 // cancel completed once the SavePage operation returns. 181 // cancel completed once the SavePage operation returns.
179 if (!pending_request_) { 182 if (!pending_request_) {
180 callback.Run(0LL); 183 callback.Run(0LL);
181 return; 184 return;
182 } 185 }
183 186
184 if (save_state_ != NONE) { 187 if (save_state_ != NONE) {
185 save_state_ = DELETE_AFTER_SAVE; 188 save_state_ = DELETE_AFTER_SAVE;
186 cancel_callback_ = callback; 189 cancel_callback_ = callback;
187 return; 190 return;
188 } 191 }
189 192
190 int64_t request_id = pending_request_->request_id(); 193 int64_t request_id = pending_request_->request_id();
191 ResetState(); 194 ResetState();
192 callback.Run(request_id); 195 callback.Run(request_id);
193 } 196 }
194 197
195 bool BackgroundLoaderOffliner::HandleTimeout(const SavePageRequest& request) { 198 bool BackgroundLoaderOffliner::HandleTimeout(const SavePageRequest& request) {
196 // TODO(romax) Decide if we want to also take a snapshot on the last timeout 199 // TODO(romax) Decide if we want to also take a snapshot on the last timeout
197 // for the background loader offliner. 200 // for the background loader offliner.
198 return false; 201 return false;
199 } 202 }
200 203
204 void BackgroundLoaderOffliner::DocumentLoadedInFrame(
205 content::RenderFrameHost* render_host) {
206 // Inform snapshot controller if in main frame.
207 if (!render_host->GetParent())
208 snapshot_controller_->DocumentAvailableInMainFrame();
209 }
210
201 void BackgroundLoaderOffliner::DidStopLoading() { 211 void BackgroundLoaderOffliner::DidStopLoading() {
202 if (!pending_request_.get()) { 212 if (!pending_request_.get()) {
203 DVLOG(1) << "DidStopLoading called even though no pending request."; 213 DVLOG(1) << "DidStopLoading called even though no pending request.";
204 return; 214 return;
205 } 215 }
206 216
207 // Invalidate ptrs for any ongoing save operation. 217 snapshot_controller_->DocumentOnLoadCompletedInMainFrame();
208 weak_ptr_factory_.InvalidateWeakPtrs();
209
210 // Post SavePage task with 2 second delay.
211 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
212 FROM_HERE,
213 base::Bind(&BackgroundLoaderOffliner::SavePage,
214 weak_ptr_factory_.GetWeakPtr()),
215 base::TimeDelta::FromMilliseconds(page_delay_ms_));
216 } 218 }
217 219
218 void BackgroundLoaderOffliner::RenderProcessGone( 220 void BackgroundLoaderOffliner::RenderProcessGone(
219 base::TerminationStatus status) { 221 base::TerminationStatus status) {
220 if (pending_request_) { 222 if (pending_request_) {
221 SavePageRequest request(*pending_request_.get()); 223 SavePageRequest request(*pending_request_.get());
222 switch (status) { 224 switch (status) {
223 case base::TERMINATION_STATUS_OOM: 225 case base::TERMINATION_STATUS_OOM:
224 case base::TERMINATION_STATUS_PROCESS_CRASHED: 226 case base::TERMINATION_STATUS_PROCESS_CRASHED:
225 case base::TERMINATION_STATUS_STILL_RUNNING: 227 case base::TERMINATION_STATUS_STILL_RUNNING:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 case net::ERR_UNKNOWN_URL_SCHEME: 281 case net::ERR_UNKNOWN_URL_SCHEME:
280 page_load_state_ = NONRETRIABLE; 282 page_load_state_ = NONRETRIABLE;
281 break; 283 break;
282 case net::ERR_INTERNET_DISCONNECTED: 284 case net::ERR_INTERNET_DISCONNECTED:
283 page_load_state_ = DELAY_RETRY; 285 page_load_state_ = DELAY_RETRY;
284 break; 286 break;
285 default: 287 default:
286 page_load_state_ = RETRIABLE; 288 page_load_state_ = RETRIABLE;
287 } 289 }
288 } 290 }
289
290 // If the document is not the same invalidate any pending save tasks.
291 //
292 // Downloads or 204/205 response codes do not commit (no new navigation)
293 // Same-Document (committed) navigations are:
294 // - reference fragment navigations
295 // - pushState/replaceState
296 // - same document history navigation
297 if (navigation_handle->HasCommitted() &&
298 !navigation_handle->IsSameDocument()) {
299 weak_ptr_factory_.InvalidateWeakPtrs();
300 }
301 } 291 }
302 292
303 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) { 293 void BackgroundLoaderOffliner::SetPageDelayForTest(long delay_ms) {
304 page_delay_ms_ = delay_ms; 294 page_delay_ms_ = delay_ms;
305 } 295 }
306 296
307 void BackgroundLoaderOffliner::OnNetworkBytesChanged(int64_t bytes) { 297 void BackgroundLoaderOffliner::OnNetworkBytesChanged(int64_t bytes) {
308 if (pending_request_ && save_state_ != SAVING) { 298 if (pending_request_ && save_state_ != SAVING) {
309 network_bytes_ += bytes; 299 network_bytes_ += bytes;
310 progress_callback_.Run(*pending_request_, network_bytes_); 300 progress_callback_.Run(*pending_request_, network_bytes_);
311 } 301 }
312 } 302 }
313 303
314 void BackgroundLoaderOffliner::SavePage() { 304 void BackgroundLoaderOffliner::StartSnapshot() {
315 if (!pending_request_.get()) { 305 if (!pending_request_.get()) {
316 DVLOG(1) << "Pending request was cleared during delay."; 306 DVLOG(1) << "Pending request was cleared during delay.";
317 return; 307 return;
318 } 308 }
319 309
320 SavePageRequest request(*pending_request_.get()); 310 SavePageRequest request(*pending_request_.get());
321 // If there was an error navigating to page, return loading failed. 311 // If there was an error navigating to page, return loading failed.
322 if (page_load_state_ != SUCCESS) { 312 if (page_load_state_ != SUCCESS) {
323 Offliner::RequestStatus status; 313 Offliner::RequestStatus status;
324 switch (page_load_state_) { 314 switch (page_load_state_) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 SavePageRequest request(*pending_request_.get()); 365 SavePageRequest request(*pending_request_.get());
376 ResetState(); 366 ResetState();
377 367
378 if (save_state_ == DELETE_AFTER_SAVE) { 368 if (save_state_ == DELETE_AFTER_SAVE) {
379 save_state_ = NONE; 369 save_state_ = NONE;
380 cancel_callback_.Run(request.request_id()); 370 cancel_callback_.Run(request.request_id());
381 return; 371 return;
382 } 372 }
383 373
384 save_state_ = NONE; 374 save_state_ = NONE;
375 // Prevent snapshot controller from making any more snapshots.
376 snapshot_controller_->Stop();
385 377
386 Offliner::RequestStatus save_status; 378 Offliner::RequestStatus save_status;
387 if (save_result == SavePageResult::SUCCESS) 379 if (save_result == SavePageResult::SUCCESS)
388 save_status = RequestStatus::SAVED; 380 save_status = RequestStatus::SAVED;
389 else 381 else
390 save_status = RequestStatus::SAVE_FAILED; 382 save_status = RequestStatus::SAVE_FAILED;
391 383
392 completion_callback_.Run(request, save_status); 384 completion_callback_.Run(request, save_status);
393 } 385 }
394 386
395 void BackgroundLoaderOffliner::ResetState() { 387 void BackgroundLoaderOffliner::ResetState() {
396 pending_request_.reset(); 388 pending_request_.reset();
389 snapshot_controller_.reset();
397 page_load_state_ = SUCCESS; 390 page_load_state_ = SUCCESS;
398 network_bytes_ = 0LL; 391 network_bytes_ = 0LL;
399 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners. 392 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners.
400 // We reset the loader and observer after completion so loaders 393 // We reset the loader and observer after completion so loaders
401 // will not be re-used across different requests/tries. This is a temporary 394 // will not be re-used across different requests/tries. This is a temporary
402 // solution while there exists assumptions about the number of offliners 395 // solution while there exists assumptions about the number of offliners
403 // there are. 396 // there are.
404 loader_.reset( 397 loader_.reset(
405 new background_loader::BackgroundLoaderContents(browser_context_)); 398 new background_loader::BackgroundLoaderContents(browser_context_));
406 content::WebContents* contents = loader_->web_contents(); 399 content::WebContents* contents = loader_->web_contents();
(...skipping 21 matching lines...) Expand all
428 int64_t offline_id) { 421 int64_t offline_id) {
429 // If for some reason the request was reset during while waiting for callback 422 // If for some reason the request was reset during while waiting for callback
430 // ignore the completion callback. 423 // ignore the completion callback.
431 if (pending_request_ && pending_request_->request_id() != offline_id) 424 if (pending_request_ && pending_request_->request_id() != offline_id)
432 return; 425 return;
433 completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED); 426 completion_callback_.Run(request, RequestStatus::FOREGROUND_CANCELED);
434 } 427 }
435 } // namespace offline_pages 428 } // namespace offline_pages
436 429
437 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData); 430 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::OfflinerData);
OLDNEW
« no previous file with comments | « chrome/browser/android/offline_pages/background_loader_offliner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698