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

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

Issue 2656763002: [Offline pages] Add navigation error handling to background loader. (Closed)
Patch Set: cl comments and format Created 3 years, 10 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/web_contents.h" 17 #include "content/public/browser/web_contents.h"
17 18
18 namespace offline_pages { 19 namespace offline_pages {
19 20
20 BackgroundLoaderOffliner::BackgroundLoaderOffliner( 21 BackgroundLoaderOffliner::BackgroundLoaderOffliner(
21 content::BrowserContext* browser_context, 22 content::BrowserContext* browser_context,
22 const OfflinerPolicy* policy, 23 const OfflinerPolicy* policy,
23 OfflinePageModel* offline_page_model) 24 OfflinePageModel* offline_page_model)
24 : browser_context_(browser_context), 25 : browser_context_(browser_context),
25 offline_page_model_(offline_page_model), 26 offline_page_model_(offline_page_model),
26 is_low_end_device_(base::SysInfo::IsLowEndDevice()), 27 is_low_end_device_(base::SysInfo::IsLowEndDevice()),
27 save_state_(NONE), 28 save_state_(NONE),
29 page_load_state_(SUCCESS),
28 weak_ptr_factory_(this) { 30 weak_ptr_factory_(this) {
29 DCHECK(offline_page_model_); 31 DCHECK(offline_page_model_);
30 DCHECK(browser_context_); 32 DCHECK(browser_context_);
31 } 33 }
32 34
33 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {} 35 BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {}
34 36
35 bool BackgroundLoaderOffliner::LoadAndSave(const SavePageRequest& request, 37 bool BackgroundLoaderOffliner::LoadAndSave(const SavePageRequest& request,
36 const CompletionCallback& callback) { 38 const CompletionCallback& callback) {
37 DCHECK(callback); 39 DCHECK(callback);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 122
121 ResetState(); 123 ResetState();
122 } 124 }
123 125
124 void BackgroundLoaderOffliner::DidStopLoading() { 126 void BackgroundLoaderOffliner::DidStopLoading() {
125 if (!pending_request_.get()) { 127 if (!pending_request_.get()) {
126 DVLOG(1) << "DidStopLoading called even though no pending request."; 128 DVLOG(1) << "DidStopLoading called even though no pending request.";
127 return; 129 return;
128 } 130 }
129 131
132 SavePageRequest request(*pending_request_.get());
133 // If there was an error navigating to page, return loading failed.
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
130 save_state_ = SAVING; 144 save_state_ = SAVING;
131 SavePageRequest request(*pending_request_.get());
132 content::WebContents* web_contents( 145 content::WebContents* web_contents(
133 content::WebContentsObserver::web_contents()); 146 content::WebContentsObserver::web_contents());
134 147
135 std::unique_ptr<OfflinePageArchiver> archiver( 148 std::unique_ptr<OfflinePageArchiver> archiver(
136 new OfflinePageMHTMLArchiver(web_contents)); 149 new OfflinePageMHTMLArchiver(web_contents));
137 150
138 OfflinePageModel::SavePageParams params; 151 OfflinePageModel::SavePageParams params;
139 params.url = web_contents->GetLastCommittedURL(); 152 params.url = web_contents->GetLastCommittedURL();
140 params.client_id = request.client_id(); 153 params.client_id = request.client_id();
141 params.proposed_offline_id = request.request_id(); 154 params.proposed_offline_id = request.request_id();
(...skipping 20 matching lines...) Expand all
162 completion_callback_.Run(request, 175 completion_callback_.Run(request,
163 Offliner::RequestStatus::LOADING_FAILED); 176 Offliner::RequestStatus::LOADING_FAILED);
164 } 177 }
165 ResetState(); 178 ResetState();
166 } 179 }
167 } 180 }
168 181
169 void BackgroundLoaderOffliner::WebContentsDestroyed() { 182 void BackgroundLoaderOffliner::WebContentsDestroyed() {
170 if (pending_request_) { 183 if (pending_request_) {
171 SavePageRequest request(*pending_request_.get()); 184 SavePageRequest request(*pending_request_.get());
172 completion_callback_.Run(*pending_request_.get(), 185 completion_callback_.Run(request, Offliner::RequestStatus::LOADING_FAILED);
173 Offliner::RequestStatus::LOADING_FAILED);
174 ResetState(); 186 ResetState();
175 } 187 }
176 } 188 }
177 189
190 void BackgroundLoaderOffliner::DidFinishNavigation(
191 content::NavigationHandle* navigation_handle) {
192 // If there was an error of any kind (certificate, client, DNS, etc),
193 // Mark as error page. Resetting here causes RecordNavigationMetrics to crash.
194 if (navigation_handle->IsErrorPage()) {
195 // TODO(chili): we need to UMA this.
196 switch (navigation_handle->GetNetErrorCode()) {
197 case net::ERR_ACCESS_DENIED:
198 case net::ERR_ADDRESS_INVALID:
199 case net::ERR_ADDRESS_UNREACHABLE:
200 case net::ERR_CERT_COMMON_NAME_INVALID:
201 case net::ERR_CERT_AUTHORITY_INVALID:
202 case net::ERR_CERT_CONTAINS_ERRORS:
203 case net::ERR_CERT_INVALID:
204 case net::ERR_CONNECTION_FAILED:
205 case net::ERR_DISALLOWED_URL_SCHEME:
206 case net::ERR_DNS_SERVER_FAILED:
207 case net::ERR_FILE_NOT_FOUND:
208 case net::ERR_FILE_PATH_TOO_LONG:
209 case net::ERR_FILE_TOO_BIG:
210 case net::ERR_FILE_VIRUS_INFECTED:
211 case net::ERR_INVALID_HANDLE:
212 case net::ERR_INVALID_RESPONSE:
213 case net::ERR_INVALID_URL:
214 case net::ERR_MSG_TOO_BIG:
215 case net::ERR_NAME_NOT_RESOLVED:
216 case net::ERR_NAME_RESOLUTION_FAILED:
217 case net::ERR_SSL_PROTOCOL_ERROR:
218 case net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED:
219 case net::ERR_SSL_SERVER_CERT_BAD_FORMAT:
220 case net::ERR_UNKNOWN_URL_SCHEME:
221 page_load_state_ = NONRETRIABLE;
222 break;
223 default:
224 page_load_state_ = RETRIABLE;
225 }
226 }
227 }
228
178 void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result, 229 void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result,
179 int64_t offline_id) { 230 int64_t offline_id) {
180 if (!pending_request_) 231 if (!pending_request_)
181 return; 232 return;
182 233
183 SavePageRequest request(*pending_request_.get()); 234 SavePageRequest request(*pending_request_.get());
184 ResetState(); 235 ResetState();
185 236
186 if (save_state_ == DELETE_AFTER_SAVE) { 237 if (save_state_ == DELETE_AFTER_SAVE) {
187 save_state_ = NONE; 238 save_state_ = NONE;
188 return; 239 return;
189 } 240 }
190 241
191 save_state_ = NONE; 242 save_state_ = NONE;
192 243
193 Offliner::RequestStatus save_status; 244 Offliner::RequestStatus save_status;
194 if (save_result == SavePageResult::SUCCESS) 245 if (save_result == SavePageResult::SUCCESS)
195 save_status = RequestStatus::SAVED; 246 save_status = RequestStatus::SAVED;
196 else 247 else
197 save_status = RequestStatus::SAVE_FAILED; 248 save_status = RequestStatus::SAVE_FAILED;
198 249
199 completion_callback_.Run(request, save_status); 250 completion_callback_.Run(request, save_status);
200 } 251 }
201 252
202 void BackgroundLoaderOffliner::ResetState() { 253 void BackgroundLoaderOffliner::ResetState() {
203 pending_request_.reset(); 254 pending_request_.reset();
255 page_load_state_ = SUCCESS;
204 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners. 256 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners.
205 // We reset the loader and observer after completion so loaders 257 // We reset the loader and observer after completion so loaders
206 // will not be re-used across different requests/tries. This is a temporary 258 // will not be re-used across different requests/tries. This is a temporary
207 // solution while there exists assumptions about the number of offliners 259 // solution while there exists assumptions about the number of offliners
208 // there are. 260 // there are.
209 loader_.reset( 261 loader_.reset(
210 new background_loader::BackgroundLoaderContents(browser_context_)); 262 new background_loader::BackgroundLoaderContents(browser_context_));
211 content::WebContentsObserver::Observe(loader_.get()->web_contents()); 263 content::WebContentsObserver::Observe(loader_.get()->web_contents());
212 } 264 }
213 265
214 void BackgroundLoaderOffliner::OnApplicationStateChange( 266 void BackgroundLoaderOffliner::OnApplicationStateChange(
215 base::android::ApplicationState application_state) { 267 base::android::ApplicationState application_state) {
216 if (pending_request_ && is_low_end_device_ && 268 if (pending_request_ && is_low_end_device_ &&
217 application_state == 269 application_state ==
218 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { 270 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
219 DVLOG(1) << "App became active, canceling current offlining request"; 271 DVLOG(1) << "App became active, canceling current offlining request";
220 SavePageRequest* request = pending_request_.get(); 272 SavePageRequest* request = pending_request_.get();
221 Cancel(); 273 Cancel();
222 completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED); 274 completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED);
223 } 275 }
224 } 276 }
225 277
226 } // namespace offline_pages 278 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698