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

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: move some errors to non-catch, so we can notify user 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 Offliner::RequestStatus::LOADING_FAILED_NO_RETRY;
137 if (page_load_state_ == RETRIABLE)
fgorski 2017/02/07 21:42:23 can you inline with ?:
chili 2017/02/11 00:32:08 Done.
138 status = Offliner::RequestStatus::LOADING_FAILED;
139 completion_callback_.Run(
fgorski 2017/02/07 21:42:23 nit: one line
chili 2017/02/11 00:32:08 Done.
140 request,
141 status);
142 ResetState();
143 return;
144 }
145
130 save_state_ = SAVING; 146 save_state_ = SAVING;
131 SavePageRequest request(*pending_request_.get());
132 content::WebContents* web_contents( 147 content::WebContents* web_contents(
133 content::WebContentsObserver::web_contents()); 148 content::WebContentsObserver::web_contents());
134 149
135 std::unique_ptr<OfflinePageArchiver> archiver( 150 std::unique_ptr<OfflinePageArchiver> archiver(
136 new OfflinePageMHTMLArchiver(web_contents)); 151 new OfflinePageMHTMLArchiver(web_contents));
137 152
138 OfflinePageModel::SavePageParams params; 153 OfflinePageModel::SavePageParams params;
139 params.url = web_contents->GetLastCommittedURL(); 154 params.url = web_contents->GetLastCommittedURL();
140 params.client_id = request.client_id(); 155 params.client_id = request.client_id();
141 params.proposed_offline_id = request.request_id(); 156 params.proposed_offline_id = request.request_id();
(...skipping 20 matching lines...) Expand all
162 completion_callback_.Run(request, 177 completion_callback_.Run(request,
163 Offliner::RequestStatus::LOADING_FAILED); 178 Offliner::RequestStatus::LOADING_FAILED);
164 } 179 }
165 ResetState(); 180 ResetState();
166 } 181 }
167 } 182 }
168 183
169 void BackgroundLoaderOffliner::WebContentsDestroyed() { 184 void BackgroundLoaderOffliner::WebContentsDestroyed() {
170 if (pending_request_) { 185 if (pending_request_) {
171 SavePageRequest request(*pending_request_.get()); 186 SavePageRequest request(*pending_request_.get());
172 completion_callback_.Run(*pending_request_.get(), 187 completion_callback_.Run(request,
173 Offliner::RequestStatus::LOADING_FAILED); 188 Offliner::RequestStatus::LOADING_FAILED);
174 ResetState(); 189 ResetState();
175 } 190 }
176 } 191 }
177 192
193 void BackgroundLoaderOffliner::DidFinishNavigation(
194 content::NavigationHandle* navigation_handle) {
195 // If there was an error of any kind (certificate, client, DNS, etc),
196 // Mark as error page. Resetting here causes RecordNavigationMetrics to crash.
197 if (navigation_handle->IsErrorPage()) {
198 // TODO(chili): we need to UMA this.
199 switch (navigation_handle->GetNetErrorCode()) {
200 case net::ERR_ACCESS_DENIED:
201 case net::ERR_ADDRESS_INVALID:
202 case net::ERR_ADDRESS_UNREACHABLE:
203 case net::ERR_CERT_COMMON_NAME_INVALID:
204 case net::ERR_CERT_AUTHORITY_INVALID:
205 case net::ERR_CERT_CONTAINS_ERRORS:
206 case net::ERR_CERT_INVALID:
207 case net::ERR_DISALLOWED_URL_SCHEME:
208 case net::ERR_FILE_NOT_FOUND:
209 case net::ERR_INVALID_URL:
210 case net::ERR_NAME_NOT_RESOLVED:
211 case net::ERR_NAME_RESOLUTION_FAILED:
212 case net::ERR_SSL_PROTOCOL_ERROR:
213 case net::ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED:
214 case net::ERR_SSL_SERVER_CERT_BAD_FORMAT:
215 case net::ERR_UNKNOWN_URL_SCHEME:
216 // For these errors, we want to show user the error page
fgorski 2017/02/07 21:42:23 so we will end with success? Do you want to snapsh
chili 2017/02/11 00:32:08 Before: yes. Per offline discussion and dmitry's
217 break;
218 case net::ERR_CONNECTION_FAILED:
219 case net::ERR_DNS_SERVER_FAILED:
220 case net::ERR_FILE_PATH_TOO_LONG:
221 case net::ERR_FILE_TOO_BIG:
222 case net::ERR_FILE_VIRUS_INFECTED:
223 case net::ERR_INVALID_HANDLE:
224 case net::ERR_INVALID_RESPONSE:
225 case net::ERR_MSG_TOO_BIG:
226 page_load_state_ = NONRETRIABLE;
227 break;
228 default:
229 page_load_state_ = RETRIABLE;
230 }
231 }
232 }
233
178 void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result, 234 void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result,
179 int64_t offline_id) { 235 int64_t offline_id) {
180 if (!pending_request_) 236 if (!pending_request_)
181 return; 237 return;
182 238
183 SavePageRequest request(*pending_request_.get()); 239 SavePageRequest request(*pending_request_.get());
184 ResetState(); 240 ResetState();
185 241
186 if (save_state_ == DELETE_AFTER_SAVE) { 242 if (save_state_ == DELETE_AFTER_SAVE) {
187 save_state_ = NONE; 243 save_state_ = NONE;
188 return; 244 return;
189 } 245 }
190 246
191 save_state_ = NONE; 247 save_state_ = NONE;
192 248
193 Offliner::RequestStatus save_status; 249 Offliner::RequestStatus save_status;
194 if (save_result == SavePageResult::SUCCESS) 250 if (save_result == SavePageResult::SUCCESS)
195 save_status = RequestStatus::SAVED; 251 save_status = RequestStatus::SAVED;
196 else 252 else
197 save_status = RequestStatus::SAVE_FAILED; 253 save_status = RequestStatus::SAVE_FAILED;
198 254
199 completion_callback_.Run(request, save_status); 255 completion_callback_.Run(request, save_status);
200 } 256 }
201 257
202 void BackgroundLoaderOffliner::ResetState() { 258 void BackgroundLoaderOffliner::ResetState() {
203 pending_request_.reset(); 259 pending_request_.reset();
260 page_load_state_ = SUCCESS;
204 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners. 261 // TODO(chili): Remove after RequestCoordinator can handle multiple offliners.
205 // We reset the loader and observer after completion so loaders 262 // We reset the loader and observer after completion so loaders
206 // will not be re-used across different requests/tries. This is a temporary 263 // will not be re-used across different requests/tries. This is a temporary
207 // solution while there exists assumptions about the number of offliners 264 // solution while there exists assumptions about the number of offliners
208 // there are. 265 // there are.
209 loader_.reset( 266 loader_.reset(
210 new background_loader::BackgroundLoaderContents(browser_context_)); 267 new background_loader::BackgroundLoaderContents(browser_context_));
211 content::WebContentsObserver::Observe(loader_.get()->web_contents()); 268 content::WebContentsObserver::Observe(loader_.get()->web_contents());
212 } 269 }
213 270
214 void BackgroundLoaderOffliner::OnApplicationStateChange( 271 void BackgroundLoaderOffliner::OnApplicationStateChange(
215 base::android::ApplicationState application_state) { 272 base::android::ApplicationState application_state) {
216 if (pending_request_ && is_low_end_device_ && 273 if (pending_request_ && is_low_end_device_ &&
217 application_state == 274 application_state ==
218 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) { 275 base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
219 DVLOG(1) << "App became active, canceling current offlining request"; 276 DVLOG(1) << "App became active, canceling current offlining request";
220 SavePageRequest* request = pending_request_.get(); 277 SavePageRequest* request = pending_request_.get();
221 Cancel(); 278 Cancel();
222 completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED); 279 completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED);
223 } 280 }
224 } 281 }
225 282
226 } // namespace offline_pages 283 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698