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

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: Incorporated comments. 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 committed_error_page_info_->error.unreachableURL ==
370 pending_error_page_info_->error.unreachableURL) {
mmenke 2014/04/11 19:42:32 suggest indenting the last line 4 more, for easier
Randy Smith (Not in Mondays) 2014/04/14 22:02:13 Done.
371 DCHECK(navigation_from_button_ == RELOAD_BUTTON ||
372 navigation_from_button_ == LOAD_STALE_BUTTON);
mmenke 2014/04/11 19:42:32 include logging.h
Randy Smith (Not in Mondays) 2014/04/14 22:02:13 Done.
373 chrome_common_net::RecordEvent(
374 navigation_from_button_ == RELOAD_BUTTON ?
375 chrome_common_net::RELOAD_BUTTON_ERROR_EVENT :
376 chrome_common_net::LOAD_STALE_BUTTON_ERROR_EVENT);
mmenke 2014/04/11 19:42:32 think this is easier to read of the last two lines
Randy Smith (Not in Mondays) 2014/04/14 22:02:13 Done.
377 }
378 navigation_from_button_ = NO_BUTTON;
379
359 if (committed_error_page_info_ && !pending_error_page_info_ && 380 if (committed_error_page_info_ && !pending_error_page_info_ &&
360 can_auto_reload_page_) { 381 can_auto_reload_page_) {
361 int reason = committed_error_page_info_->error.reason; 382 int reason = committed_error_page_info_->error.reason;
362 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess", 383 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess",
363 -reason, 384 -reason,
364 net::GetAllErrorCodesForUma()); 385 net::GetAllErrorCodesForUma());
365 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", auto_reload_count_); 386 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", auto_reload_count_);
366 if (auto_reload_count_ == 1) { 387 if (auto_reload_count_ == 1) {
367 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess", 388 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess",
368 -reason, 389 -reason,
369 net::GetAllErrorCodesForUma()); 390 net::GetAllErrorCodesForUma());
370 } 391 }
371 } 392 }
372 393
373 committed_error_page_info_.reset(pending_error_page_info_.release()); 394 committed_error_page_info_.reset(pending_error_page_info_.release());
374 } 395 }
375 396
376 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { 397 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
377 if (frame_type != MAIN_FRAME) 398 if (frame_type != MAIN_FRAME)
378 return; 399 return;
379 400
380 if (!committed_error_page_info_) { 401 if (!committed_error_page_info_) {
381 auto_reload_count_ = 0; 402 auto_reload_count_ = 0;
382 return; 403 return;
383 } 404 }
384 405
385 committed_error_page_info_->is_finished_loading = true; 406 committed_error_page_info_->is_finished_loading = true;
386 407
387 // Only enable stale cache JS bindings if this wasn't a post. 408 chrome_common_net::RecordEvent(chrome_common_net::PAGE_SHOWN_EVENT);
388 if (!committed_error_page_info_->was_failed_post) { 409 if (committed_error_page_info_->reload_button_in_page) {
389 delegate_->EnableStaleLoadBindings( 410 chrome_common_net::RecordEvent(
390 committed_error_page_info_->error.unreachableURL); 411 chrome_common_net::RELOAD_BUTTON_SHOWN_EVENT);
391 } 412 }
413 if (committed_error_page_info_->load_stale_button_in_page) {
414 chrome_common_net::RecordEvent(
415 chrome_common_net::LOAD_STALE_BUTTON_SHOWN_EVENT);
416 }
417
418 delegate_->EnablePageHelperFunctions();
392 419
393 if (committed_error_page_info_->navigation_correction_url.is_valid()) { 420 if (committed_error_page_info_->navigation_correction_url.is_valid()) {
394 // If there is another pending error page load, |fix_url| should have been 421 // If there is another pending error page load, |fix_url| should have been
395 // cleared. 422 // cleared.
396 DCHECK(!pending_error_page_info_); 423 DCHECK(!pending_error_page_info_);
397 DCHECK(!committed_error_page_info_->needs_dns_updates); 424 DCHECK(!committed_error_page_info_->needs_dns_updates);
398 delegate_->FetchNavigationCorrections( 425 delegate_->FetchNavigationCorrections(
399 committed_error_page_info_->navigation_correction_url, 426 committed_error_page_info_->navigation_correction_url,
400 committed_error_page_info_->navigation_correction_request_body); 427 committed_error_page_info_->navigation_correction_request_body);
401 } else if (auto_reload_enabled_ && 428 } 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)); 486 pending_error_page_info_.reset(new ErrorPageInfo(error, is_failed_post));
460 // Skip DNS logic if suggestions were received from a remote server. 487 // Skip DNS logic if suggestions were received from a remote server.
461 if (IsDnsError(error) && !params) { 488 if (IsDnsError(error) && !params) {
462 // This is not strictly necessary, but waiting for a new status to be 489 // 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 490 // sent as a result of the DidFinishLoading call keeps the histograms
464 // consistent with older versions of the code, at no real cost. 491 // consistent with older versions of the code, at no real cost.
465 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE; 492 last_probe_status_ = chrome_common_net::DNS_PROBE_POSSIBLE;
466 493
467 delegate_->GenerateLocalizedErrorPage( 494 delegate_->GenerateLocalizedErrorPage(
468 GetUpdatedError(error), is_failed_post, params.Pass(), 495 GetUpdatedError(error), is_failed_post, params.Pass(),
496 &pending_error_page_info_->reload_button_in_page,
497 &pending_error_page_info_->load_stale_button_in_page,
469 error_html); 498 error_html);
470 pending_error_page_info_->needs_dns_updates = true; 499 pending_error_page_info_->needs_dns_updates = true;
471 return; 500 return;
472 } 501 }
473 } 502 }
474 503
475 delegate_->GenerateLocalizedErrorPage(error, is_failed_post, 504 bool reload_button_in_page = false;
476 params.Pass(), error_html); 505 bool load_stale_button_in_page = false;
506 delegate_->GenerateLocalizedErrorPage(
507 error, is_failed_post, params.Pass(),
508 &reload_button_in_page, &load_stale_button_in_page, error_html);
509 if (pending_error_page_info_) {
510 pending_error_page_info_->reload_button_in_page = reload_button_in_page;
511 pending_error_page_info_->load_stale_button_in_page =
512 load_stale_button_in_page;
513 }
477 } 514 }
478 515
479 void NetErrorHelperCore::OnNetErrorInfo( 516 void NetErrorHelperCore::OnNetErrorInfo(
480 chrome_common_net::DnsProbeStatus status) { 517 chrome_common_net::DnsProbeStatus status) {
481 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status); 518 DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, status);
482 519
483 last_probe_status_ = status; 520 last_probe_status_ = status;
484 521
485 if (!committed_error_page_info_ || 522 if (!committed_error_page_info_ ||
486 !committed_error_page_info_->needs_dns_updates || 523 !committed_error_page_info_->needs_dns_updates ||
(...skipping 24 matching lines...) Expand all
511 548
512 UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus", 549 UMA_HISTOGRAM_ENUMERATION("DnsProbe.ErrorPageUpdateStatus",
513 last_probe_status_, 550 last_probe_status_,
514 chrome_common_net::DNS_PROBE_MAX); 551 chrome_common_net::DNS_PROBE_MAX);
515 // Every status other than DNS_PROBE_POSSIBLE and DNS_PROBE_STARTED is a 552 // 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 553 // final status code. Once one is reached, the page does not need further
517 // updates. 554 // updates.
518 if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED) 555 if (last_probe_status_ != chrome_common_net::DNS_PROBE_STARTED)
519 committed_error_page_info_->needs_dns_updates = false; 556 committed_error_page_info_->needs_dns_updates = false;
520 557
558 // There is no need to worry about the button display statistics here because
559 // the presentation of the reload and load stale buttons can't be changed
560 // by a DNS error update.
521 delegate_->UpdateErrorPage( 561 delegate_->UpdateErrorPage(
522 GetUpdatedError(committed_error_page_info_->error), 562 GetUpdatedError(committed_error_page_info_->error),
523 committed_error_page_info_->was_failed_post); 563 committed_error_page_info_->was_failed_post);
524 } 564 }
525 565
526 void NetErrorHelperCore::OnNavigationCorrectionsFetched( 566 void NetErrorHelperCore::OnNavigationCorrectionsFetched(
527 const std::string& corrections, 567 const std::string& corrections,
528 const std::string& accept_languages, 568 const std::string& accept_languages,
529 bool is_rtl) { 569 bool is_rtl) {
530 // Loading suggestions only starts when a blank error page finishes loading, 570 // 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) 683 if (error_url != url)
644 return false; 684 return false;
645 685
646 // The first iteration of the timer is started by OnFinishLoad calling 686 // The first iteration of the timer is started by OnFinishLoad calling
647 // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are 687 // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are
648 // suppressed in this function, subsequent iterations of the timer have to be 688 // suppressed in this function, subsequent iterations of the timer have to be
649 // started here. 689 // started here.
650 MaybeStartAutoReloadTimer(); 690 MaybeStartAutoReloadTimer();
651 return true; 691 return true;
652 } 692 }
693
694 void NetErrorHelperCore::ExecuteButtonPress(Button button) {
695 switch (button) {
696 case RELOAD_BUTTON:
697 chrome_common_net::RecordEvent(
698 chrome_common_net::RELOAD_BUTTON_CLICKED_EVENT);
699 navigation_from_button_ = RELOAD_BUTTON;
700 Reload();
701 return;
702 case LOAD_STALE_BUTTON:
703 chrome_common_net::RecordEvent(
704 chrome_common_net::LOAD_STALE_BUTTON_CLICKED_EVENT);
705 navigation_from_button_ = LOAD_STALE_BUTTON;
706 delegate_->LoadPageFromCache(
707 committed_error_page_info_->error.unreachableURL);
708 return;
709 case MORE_BUTTON:
710 // Visual effects on page are handled in Javascript code.
711 chrome_common_net::RecordEvent(
712 chrome_common_net::MORE_BUTTON_CLICKED_EVENT);
713 return;
714 case NO_BUTTON:
715 NOTREACHED();
716 return;
717 }
718 }
719
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698