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

Side by Side Diff: chrome/renderer/net/net_error_helper_core.cc

Issue 207553008: Surface button for loading stale cache copy on net error page. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor tweaks from self-review. Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/renderer/net/net_error_helper_core.h" 5 #include "chrome/renderer/net/net_error_helper_core.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 return params.release(); 246 return params.release();
247 } 247 }
248 248
249 } // namespace 249 } // namespace
250 250
251 struct NetErrorHelperCore::ErrorPageInfo { 251 struct NetErrorHelperCore::ErrorPageInfo {
252 ErrorPageInfo(blink::WebURLError error, bool was_failed_post) 252 ErrorPageInfo(blink::WebURLError error, bool was_failed_post)
253 : error(error), 253 : error(error),
254 was_failed_post(was_failed_post), 254 was_failed_post(was_failed_post),
255 needs_dns_updates(false), 255 needs_dns_updates(false),
256 reload_button_in_page(false),
257 load_stale_button_in_page(false),
256 is_finished_loading(false) { 258 is_finished_loading(false) {
257 } 259 }
258 260
259 // Information about the failed page load. 261 // Information about the failed page load.
260 blink::WebURLError error; 262 blink::WebURLError error;
261 bool was_failed_post; 263 bool was_failed_post;
262 264
263 // Information about the status of the error page. 265 // Information about the status of the error page.
264 266
265 // True if a page is a DNS error page and has not yet received a final DNS 267 // True if a page is a DNS error page and has not yet received a final DNS
266 // probe status. 268 // probe status.
267 bool needs_dns_updates; 269 bool needs_dns_updates;
268 270
269 // Navigation correction service url, which will be used in response to 271 // Navigation correction service url, which will be used in response to
270 // certain types of network errors. This is also stored by the 272 // certain types of network errors. This is also stored by the
271 // NetErrorHelperCore itself, but it stored here as well in case its modified 273 // NetErrorHelperCore itself, but it stored here as well in case its modified
272 // in the middle of an error page load. Empty when no error page should be 274 // in the middle of an error page load. Empty when no error page should be
273 // fetched, or if there's already a fetch in progress. 275 // fetched, or if there's already a fetch in progress.
274 GURL navigation_correction_url; 276 GURL navigation_correction_url;
275 277
276 // Request body to use when requesting corrections from a web service. 278 // Request body to use when requesting corrections from a web service.
277 // TODO(mmenke): Investigate loading the error page at the same time as 279 // TODO(mmenke): Investigate loading the error page at the same time as
278 // the blank page is loading, to get rid of these. 280 // the blank page is loading, to get rid of these.
279 std::string navigation_correction_request_body; 281 std::string navigation_correction_request_body;
280 282
283 // Track if specific buttons are included in an error page, for statistics.
284 bool reload_button_in_page;
285 bool load_stale_button_in_page;
286
281 // True if a page has completed loading, at which point it can receive 287 // True if a page has completed loading, at which point it can receive
282 // updates. 288 // updates.
283 bool is_finished_loading; 289 bool is_finished_loading;
284 }; 290 };
285 291
286 bool NetErrorHelperCore::IsReloadableError( 292 bool NetErrorHelperCore::IsReloadableError(
287 const NetErrorHelperCore::ErrorPageInfo& info) { 293 const NetErrorHelperCore::ErrorPageInfo& info) {
288 return info.error.domain.utf8() == net::kErrorDomain && 294 return info.error.domain.utf8() == net::kErrorDomain &&
289 info.error.reason != net::ERR_ABORTED && 295 info.error.reason != net::ERR_ABORTED &&
290 !info.was_failed_post; 296 !info.was_failed_post;
291 } 297 }
292 298
293 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) 299 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate)
294 : delegate_(delegate), 300 : delegate_(delegate),
295 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE), 301 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE),
296 auto_reload_enabled_(false), 302 auto_reload_enabled_(false),
297 auto_reload_timer_(new base::Timer(false, false)), 303 auto_reload_timer_(new base::Timer(false, false)),
298 // TODO(ellyjones): Make online_ accurate at object creation. 304 // TODO(ellyjones): Make online_ accurate at object creation.
299 online_(true), 305 online_(true),
300 auto_reload_count_(0), 306 auto_reload_count_(0),
301 can_auto_reload_page_(false) { 307 can_auto_reload_page_(false),
308 navigation_from_button_(NO_BUTTON) {
302 } 309 }
303 310
304 NetErrorHelperCore::~NetErrorHelperCore() { 311 NetErrorHelperCore::~NetErrorHelperCore() {
305 if (committed_error_page_info_ && can_auto_reload_page_) { 312 if (committed_error_page_info_ && can_auto_reload_page_) {
306 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop", 313 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop",
307 -committed_error_page_info_->error.reason, 314 -committed_error_page_info_->error.reason,
308 net::GetAllErrorCodesForUma()); 315 net::GetAllErrorCodesForUma());
309 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_); 316 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_);
310 } 317 }
311 } 318 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 } else { 356 } else {
350 // If an error load is starting, the resulting error page is autoreloadable. 357 // If an error load is starting, the resulting error page is autoreloadable.
351 can_auto_reload_page_ = IsReloadableError(*pending_error_page_info_); 358 can_auto_reload_page_ = IsReloadableError(*pending_error_page_info_);
352 } 359 }
353 } 360 }
354 361
355 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { 362 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) {
356 if (frame_type != MAIN_FRAME) 363 if (frame_type != MAIN_FRAME)
357 return; 364 return;
358 365
366 // Track if an error occurred due to a page button press.
367 if (committed_error_page_info_ && pending_error_page_info_ &&
368 navigation_from_button_ != NO_BUTTON) {
369 DCHECK(navigation_from_button_ == RELOAD_BUTTON ||
370 navigation_from_button_ == LOAD_STALE_BUTTON);
371 chrome_common_net::RecordEvent(
372 navigation_from_button_ == RELOAD_BUTTON ?
373 chrome_common_net::RELOAD_BUTTON_ERROR_EVENT :
374 chrome_common_net::LOAD_STALE_BUTTON_ERROR_EVENT);
375 }
376 navigation_from_button_ = NO_BUTTON;
mmenke 2014/04/09 15:59:26 Problem: Navigate to foo.com/, get an error. Cli
Randy Smith (Not in Mondays) 2014/04/10 21:51:01 Good point. I added in a test to make sure it was
mmenke 2014/04/11 19:42:32 This still isn't perfect, but it's probably good e
Randy Smith (Not in Mondays) 2014/04/14 22:02:13 I've added a comment, but I'd like to get a design
davidben 2014/04/15 22:04:38 Hrm. So I don't entirely follow what's going on he
377
359 if (committed_error_page_info_ && !pending_error_page_info_ && 378 if (committed_error_page_info_ && !pending_error_page_info_ &&
360 can_auto_reload_page_) { 379 can_auto_reload_page_) {
361 int reason = committed_error_page_info_->error.reason; 380 int reason = committed_error_page_info_->error.reason;
362 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess", 381 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess",
363 -reason, 382 -reason,
364 net::GetAllErrorCodesForUma()); 383 net::GetAllErrorCodesForUma());
365 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", auto_reload_count_); 384 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", auto_reload_count_);
366 if (auto_reload_count_ == 1) { 385 if (auto_reload_count_ == 1) {
367 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess", 386 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess",
368 -reason, 387 -reason,
369 net::GetAllErrorCodesForUma()); 388 net::GetAllErrorCodesForUma());
370 } 389 }
371 } 390 }
372 391
373 committed_error_page_info_.reset(pending_error_page_info_.release()); 392 committed_error_page_info_.reset(pending_error_page_info_.release());
374 } 393 }
375 394
376 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { 395 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
377 if (frame_type != MAIN_FRAME) 396 if (frame_type != MAIN_FRAME)
378 return; 397 return;
379 398
380 if (!committed_error_page_info_) { 399 if (!committed_error_page_info_) {
381 auto_reload_count_ = 0; 400 auto_reload_count_ = 0;
382 return; 401 return;
383 } 402 }
384 403
385 committed_error_page_info_->is_finished_loading = true; 404 committed_error_page_info_->is_finished_loading = true;
386 405
387 // Only enable stale cache JS bindings if this wasn't a post. 406 chrome_common_net::RecordEvent(chrome_common_net::PAGE_SHOWN_EVENT);
388 if (!committed_error_page_info_->was_failed_post) { 407 if (committed_error_page_info_->reload_button_in_page)
389 delegate_->EnableStaleLoadBindings( 408 chrome_common_net::RecordEvent(
390 committed_error_page_info_->error.unreachableURL); 409 chrome_common_net::RELOAD_BUTTON_SHOWN_EVENT);
391 } 410 if (committed_error_page_info_->load_stale_button_in_page)
411 chrome_common_net::RecordEvent(
412 chrome_common_net::LOAD_STALE_BUTTON_SHOWN_EVENT);
mmenke 2014/04/09 15:59:26 nit: Use braces on multi-line if's (x2).
Randy Smith (Not in Mondays) 2014/04/10 21:51:01 Done.
413
414 delegate_->EnablePageHelperFunctions(
415 committed_error_page_info_->error.unreachableURL);
392 416
393 if (committed_error_page_info_->navigation_correction_url.is_valid()) { 417 if (committed_error_page_info_->navigation_correction_url.is_valid()) {
394 // If there is another pending error page load, |fix_url| should have been 418 // If there is another pending error page load, |fix_url| should have been
395 // cleared. 419 // cleared.
396 DCHECK(!pending_error_page_info_); 420 DCHECK(!pending_error_page_info_);
397 DCHECK(!committed_error_page_info_->needs_dns_updates); 421 DCHECK(!committed_error_page_info_->needs_dns_updates);
398 delegate_->FetchNavigationCorrections( 422 delegate_->FetchNavigationCorrections(
399 committed_error_page_info_->navigation_correction_url, 423 committed_error_page_info_->navigation_correction_url,
400 committed_error_page_info_->navigation_correction_request_body); 424 committed_error_page_info_->navigation_correction_request_body);
401 } else if (auto_reload_enabled_ && 425 } else if (auto_reload_enabled_ &&
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post)); 483 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
460 // Skip DNS logic if suggestions were received from a remote server. 484 // Skip DNS logic if suggestions were received from a remote server.
461 if (IsDnsError(error) && !params) { 485 if (IsDnsError(error) && !params) {
462 // This is not strictly necessary, but waiting for a new status to be 486 // This is not strictly necessary, but waiting for a new status to be
463 // sent as a result of the DidFinishLoading call keeps the histograms 487 // sent as a result of the DidFinishLoading call keeps the histograms
464 // consistent with older versions of the code, at no real cost. 488 // consistent with older versions of the code, at no real cost.
465 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE; 489 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
466 490
467 delegate_->GenerateLocalizedErrorPage( 491 delegate_->GenerateLocalizedErrorPage(
468 GetUpdatedError(error), is_failed_post, params.Pass(), 492 GetUpdatedError(error), is_failed_post, params.Pass(),
493 &pending_error_page_info_->reload_button_in_page,
494 &pending_error_page_info_->load_stale_button_in_page,
469 error_html); 495 error_html);
470 pending_error_page_info_->needs_dns_updates = true; 496 pending_error_page_info_->needs_dns_updates = true;
471 return; 497 return;
472 } 498 }
473 } 499 }
474 500
475 delegate_->GenerateLocalizedErrorPage(error, is_failed_post, 501 bool reload_button_in_page = false;
476 params.Pass(), error_html); 502 bool load_stale_button_in_page = false;
503 delegate_->GenerateLocalizedErrorPage(
504 error, is_failed_post, params.Pass(),
505 &reload_button_in_page, &load_stale_button_in_page, error_html);
506 if (pending_error_page_info_.get()) {
mmenke 2014/04/09 15:59:26 nit: .get() not needed.
Randy Smith (Not in Mondays) 2014/04/10 21:51:01 Done.
507 pending_error_page_info_->reload_button_in_page = reload_button_in_page;
508 pending_error_page_info_->load_stale_button_in_page =
509 load_stale_button_in_page;
510 }
477 } 511 }
478 512
479 void NetErrorHelperCore::OnNetErrorInfo( 513 void NetErrorHelperCore::OnNetErrorInfo(
480 chrome_common_net::DnsProbeStatus status) { 514 chrome_common_net::DnsProbeStatus status) {
481 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status); 515 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status);
482 516
483 last_probe_status_ = status; 517 last_probe_status_ = status;
484 518
485 if (!committed_error_page_info_ || 519 if (!committed_error_page_info_ ||
486 !committed_error_page_info_->needs_dns_updates || 520 !committed_error_page_info_->needs_dns_updates ||
(...skipping 24 matching lines...) Expand all
511 545
512 UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus", 546 UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus",
513 last_probe_status_, 547 last_probe_status_,
514 chrome_common_net::DNS_PROBE_MAX); 548 chrome_common_net::DNS_PROBE_MAX);
515 // Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a 549 // Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a
516 // final status code. Once one is reached, the page does not need further 550 // final status code. Once one is reached, the page does not need further
517 // updates. 551 // updates.
518 if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED) 552 if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED)
519 committed_error_page_info_->needs_dns_updates = false; 553 committed_error_page_info_->needs_dns_updates = false;
520 554
555 // We don't worry about the button display statistics here because
556 // the presentation of the reload and load stale buttons can't be
557 // changed by a DNS error update.
mmenke 2014/04/09 15:59:26 nit: Don't use we in comments.
Randy Smith (Not in Mondays) 2014/04/10 21:51:01 Done.
521 delegate_->UpdateErrorPage( 558 delegate_->UpdateErrorPage(
522 GetUpdatedError(committed_error_page_info_->error), 559 GetUpdatedError(committed_error_page_info_->error),
523 committed_error_page_info_->was_failed_post); 560 committed_error_page_info_->was_failed_post);
524 } 561 }
525 562
526 void NetErrorHelperCore::OnNavigationCorrectionsFetched( 563 void NetErrorHelperCore::OnNavigationCorrectionsFetched(
527 const std::string& corrections, 564 const std::string& corrections,
528 const std::string& accept_languages, 565 const std::string& accept_languages,
529 bool is_rtl) { 566 bool is_rtl) {
530 // Loading suggestions only starts when a blank error page finishes loading, 567 // Loading suggestions only starts when a blank error page finishes loading,
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 if (error_url != url) 680 if (error_url != url)
644 return false; 681 return false;
645 682
646 // The first iteration of the timer is started by OnFinishLoad calling 683 // The first iteration of the timer is started by OnFinishLoad calling
647 // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are 684 // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are
648 // suppressed in this function, subsequent iterations of the timer have to be 685 // suppressed in this function, subsequent iterations of the timer have to be
649 // started here. 686 // started here.
650 MaybeStartAutoReloadTimer(); 687 MaybeStartAutoReloadTimer();
651 return true; 688 return true;
652 } 689 }
690
691 void NetErrorHelperCore::ExecuteButtonPress(Button button) {
692 switch (button) {
693 case RELOAD_BUTTON:
694 chrome_common_net::RecordEvent(
695 chrome_common_net::RELOAD_BUTTON_CLICKED_EVENT);
696 navigation_from_button_ = RELOAD_BUTTON;
697 Reload();
698 return;
699 case LOAD_STALE_BUTTON:
700 chrome_common_net::RecordEvent(
701 chrome_common_net::LOAD_STALE_BUTTON_CLICKED_EVENT);
702 navigation_from_button_ = LOAD_STALE_BUTTON;
703 delegate_->LoadPageFromCache(
704 committed_error_page_info_->error.unreachableURL);
705 return;
706 case MORE_BUTTON:
707 // Visual effects on page are handled in Javascript code.
708 chrome_common_net::RecordEvent(
709 chrome_common_net::MORE_BUTTON_CLICKED_EVENT);
710 return;
711 case NO_BUTTON:
712 NOTREACHED();
713 return;
714 }
715 }
716
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698