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

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

Issue 2007783002: Adds PrerenderingOffliner implementation for handling Loader callbacks and then performing SavePage… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ploader
Patch Set: Update for petewil comment Created 4 years, 7 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/prerendering_offliner.h" 5 #include "chrome/browser/android/offline_pages/prerendering_offliner.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
8 #include "components/offline_pages/background/save_page_request.h" 9 #include "components/offline_pages/background/save_page_request.h"
9 #include "content/public/browser/browser_context.h" 10 #include "content/public/browser/browser_context.h"
10 11
11 namespace offline_pages { 12 namespace offline_pages {
12 13
13 PrerenderingOffliner::PrerenderingOffliner( 14 PrerenderingOffliner::PrerenderingOffliner(
14 content::BrowserContext* browser_context, 15 content::BrowserContext* browser_context,
15 const OfflinerPolicy* policy, 16 const OfflinerPolicy* policy,
16 OfflinePageModel* offline_page_model) 17 OfflinePageModel* offline_page_model)
17 : browser_context_(browser_context), 18 : browser_context_(browser_context),
18 offline_page_model_(offline_page_model), 19 offline_page_model_(offline_page_model),
20 pending_request_(nullptr),
19 weak_ptr_factory_(this) {} 21 weak_ptr_factory_(this) {}
20 22
21 PrerenderingOffliner::~PrerenderingOffliner() {} 23 PrerenderingOffliner::~PrerenderingOffliner() {}
22 24
23 void PrerenderingOffliner::OnLoadPageDone(Offliner::RequestStatus load_status, 25 void PrerenderingOffliner::OnLoadPageDone(
24 content::WebContents* contents) { 26 const SavePageRequest& request,
25 // TODO(dougarnett): Implement save attempt and running CompletionCallback. 27 const CompletionCallback& completion_callback,
28 Offliner::RequestStatus load_status,
29 content::WebContents* web_contents) {
30 // Check if request is still pending receiving a callback.
31 // Note: it is possible to get a loaded page, start the save operation,
32 // and then get another callback from the Loader (eg, if its loaded
33 // WebContents is being destroyed for some resource reclamation).
34 if (!pending_request_)
35 return;
36
37 // Since we are able to stop/cancel a previous load request, we should
38 // never see a callback for an older request when we have a newer one
39 // pending. Crash for debug build and ignore for production build.
40 DCHECK_EQ(request.request_id(), pending_request_->request_id());
41 if (request.request_id() != pending_request_->request_id()) {
42 DVLOG(1) << "Ignoring load callback for old request";
43 return;
44 }
45
46 if (load_status == Offliner::RequestStatus::LOADED) {
47 // The page has successfully loaded so now try to save the page.
48 // After issuing the save request we will wait for either: the save
49 // callback or a CANCELED load callback (triggered because the loaded
50 // WebContents are being destroyed) - whichever callback occurs first.
51 DCHECK(web_contents);
52 std::unique_ptr<OfflinePageArchiver> archiver(
53 new OfflinePageMHTMLArchiver(web_contents));
54 SavePage(request.url(), request.client_id(), std::move(archiver),
55 base::Bind(&PrerenderingOffliner::OnSavePageDone,
56 weak_ptr_factory_.GetWeakPtr(), request,
57 completion_callback));
58 } else {
59 // Clear pending request and then run the completion callback.
60 pending_request_ = nullptr;
61 completion_callback.Run(request, load_status);
62 }
63 }
64
65 void PrerenderingOffliner::OnSavePageDone(
66 const SavePageRequest& request,
67 const CompletionCallback& completion_callback,
68 SavePageResult save_result,
69 int64_t offline_id) {
70 // Check if request is still pending receiving a callback.
71 if (!pending_request_)
72 return;
73
74 // Also check that save callback is for same request as pending request
75 // (since SavePage request is not cancel-able currently and could be old).
76 if (request.request_id() != pending_request_->request_id()) {
77 DVLOG(1) << "Ignoring save callback for old request";
78 return;
79 }
80
81 // Clear pending request here and inform loader we are done with WebContents.
82 pending_request_ = nullptr;
83 GetOrCreateLoader()->StopLoading();
84
85 // Determine status and run the completion callback.
86 Offliner::RequestStatus save_status;
87 if (save_result == SavePageResult::SUCCESS) {
88 save_status = RequestStatus::SAVED;
89 } else {
90 // TODO(dougarnett): Consider reflecting some recommendation to retry the
91 // request based on specific save error cases.
92 save_status = RequestStatus::FAILED_SAVE;
93 }
94 completion_callback.Run(request, save_status);
26 } 95 }
27 96
28 bool PrerenderingOffliner::LoadAndSave(const SavePageRequest& request, 97 bool PrerenderingOffliner::LoadAndSave(const SavePageRequest& request,
29 const CompletionCallback& callback) { 98 const CompletionCallback& callback) {
30 if (!offline_page_model_->CanSavePage(request.url())) 99 if (pending_request_) {
100 DVLOG(1) << "Already have pending request";
31 return false; 101 return false;
102 }
103
104 if (!CanSavePage(request.url())) {
105 DVLOG(1) << "Not able to save page";
106 return false;
107 }
108
109 // Track pending request for callback handling.
110 pending_request_ = &request;
32 111
33 // Kick off load page attempt. 112 // Kick off load page attempt.
34 return GetOrCreateLoader()->LoadPage( 113 bool accepted = GetOrCreateLoader()->LoadPage(
35 request.url(), base::Bind(&PrerenderingOffliner::OnLoadPageDone, 114 request.url(),
36 weak_ptr_factory_.GetWeakPtr())); 115 base::Bind(&PrerenderingOffliner::OnLoadPageDone,
116 weak_ptr_factory_.GetWeakPtr(), request, callback));
117 if (!accepted)
118 pending_request_ = nullptr;
119
120 return accepted;
37 } 121 }
38 122
39 void PrerenderingOffliner::Cancel() { 123 void PrerenderingOffliner::Cancel() {
40 GetOrCreateLoader()->StopLoading(); 124 if (pending_request_) {
125 pending_request_ = nullptr;
126 GetOrCreateLoader()->StopLoading();
127 // TODO(dougarnett): Consider ability to cancel SavePage request.
128 }
41 } 129 }
42 130
43 void PrerenderingOffliner::SetLoaderForTesting( 131 void PrerenderingOffliner::SetLoaderForTesting(
44 std::unique_ptr<PrerenderingLoader> loader) { 132 std::unique_ptr<PrerenderingLoader> loader) {
45 DCHECK(!loader_); 133 DCHECK(!loader_);
46 loader_ = std::move(loader); 134 loader_ = std::move(loader);
47 } 135 }
48 136
137 bool PrerenderingOffliner::CanSavePage(const GURL& url) {
138 if (!offline_page_model_) {
139 // Assume we can save if no OfflinePageModel (for unit tests).
140 // TODO(dougarnett): Make OfflinePageModel::CanSavePage() mockable for test.
141 return true;
142 }
143 return offline_page_model_->CanSavePage(url);
144 }
145
146 void PrerenderingOffliner::SavePage(
147 const GURL& url,
148 const ClientId& client_id,
149 std::unique_ptr<OfflinePageArchiver> archiver,
150 const SavePageCallback& callback) {
151 DCHECK(offline_page_model_);
152 offline_page_model_->SavePage(url, client_id, std::move(archiver), callback);
153 }
154
49 PrerenderingLoader* PrerenderingOffliner::GetOrCreateLoader() { 155 PrerenderingLoader* PrerenderingOffliner::GetOrCreateLoader() {
50 if (!loader_) { 156 if (!loader_) {
51 loader_.reset(new PrerenderingLoader(browser_context_)); 157 loader_.reset(new PrerenderingLoader(browser_context_));
52 } 158 }
53 return loader_.get(); 159 return loader_.get();
54 } 160 }
55 161
56 } // namespace offline_pages 162 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698