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

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

Issue 259613003: Fix auto-reload histograms. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Correctly terminate uncommitted loads Created 6 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 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 <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/i18n/rtl.h" 13 #include "base/i18n/rtl.h"
14 #include "base/json/json_reader.h" 14 #include "base/json/json_reader.h"
15 #include "base/json/json_value_converter.h" 15 #include "base/json/json_value_converter.h"
16 #include "base/json/json_writer.h" 16 #include "base/json/json_writer.h"
17 #include "base/location.h" 17 #include "base/location.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/memory/scoped_vector.h" 19 #include "base/memory/scoped_vector.h"
20 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
21 #include "base/strings/string16.h" 21 #include "base/strings/string16.h"
22 #include "base/strings/string_util.h" 22 #include "base/strings/string_util.h"
23 #include "base/values.h" 23 #include "base/values.h"
24 #include "chrome/common/localized_error.h" 24 #include "chrome/common/localized_error.h"
25 #include "content/public/common/url_constants.h"
25 #include "grit/generated_resources.h" 26 #include "grit/generated_resources.h"
26 #include "net/base/escape.h" 27 #include "net/base/escape.h"
27 #include "net/base/net_errors.h" 28 #include "net/base/net_errors.h"
28 #include "net/base/net_util.h" 29 #include "net/base/net_util.h"
29 #include "third_party/WebKit/public/platform/WebString.h" 30 #include "third_party/WebKit/public/platform/WebString.h"
30 #include "third_party/WebKit/public/platform/WebURLError.h" 31 #include "third_party/WebKit/public/platform/WebURLError.h"
31 #include "ui/base/l10n/l10n_util.h" 32 #include "ui/base/l10n/l10n_util.h"
32 #include "url/gurl.h" 33 #include "url/gurl.h"
33 34
34 namespace { 35 namespace {
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 params->override_suggestions->Append(suggest); 334 params->override_suggestions->Append(suggest);
334 break; 335 break;
335 } 336 }
336 } 337 }
337 338
338 if (params->override_suggestions->empty() && !params->search_url.is_valid()) 339 if (params->override_suggestions->empty() && !params->search_url.is_valid())
339 params.reset(); 340 params.reset();
340 return params.Pass(); 341 return params.Pass();
341 } 342 }
342 343
344 void ReportAutoReloadSuccess(const blink::WebURLError& error, size_t count) {
345 if (error.domain.utf8() != net::kErrorDomain)
346 return;
347 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess",
348 -error.reason,
349 net::GetAllErrorCodesForUma());
350 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", count);
351 if (count == 1) {
352 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess",
353 -error.reason,
354 net::GetAllErrorCodesForUma());
355 }
356 }
357
358 void ReportAutoReloadFailure(const blink::WebURLError& error, size_t count) {
359 if (error.domain.utf8() != net::kErrorDomain)
360 return;
361 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop",
362 -error.reason,
363 net::GetAllErrorCodesForUma());
364 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", count);
365 }
366
343 } // namespace 367 } // namespace
344 368
345 struct NetErrorHelperCore::ErrorPageInfo { 369 struct NetErrorHelperCore::ErrorPageInfo {
346 ErrorPageInfo(blink::WebURLError error, bool was_failed_post) 370 ErrorPageInfo(blink::WebURLError error, bool was_failed_post)
347 : error(error), 371 : error(error),
348 was_failed_post(was_failed_post), 372 was_failed_post(was_failed_post),
349 needs_dns_updates(false), 373 needs_dns_updates(false),
350 needs_load_navigation_corrections(false), 374 needs_load_navigation_corrections(false),
351 reload_button_in_page(false), 375 reload_button_in_page(false),
352 load_stale_button_in_page(false), 376 load_stale_button_in_page(false),
353 is_finished_loading(false) { 377 is_finished_loading(false),
378 auto_reload_triggered(false) {
354 } 379 }
355 380
356 // Information about the failed page load. 381 // Information about the failed page load.
357 blink::WebURLError error; 382 blink::WebURLError error;
358 bool was_failed_post; 383 bool was_failed_post;
359 384
360 // Information about the status of the error page. 385 // Information about the status of the error page.
361 386
362 // True if a page is a DNS error page and has not yet received a final DNS 387 // True if a page is a DNS error page and has not yet received a final DNS
363 // probe status. 388 // probe status.
(...skipping 15 matching lines...) Expand all
379 // purposes. 404 // purposes.
380 std::set<int> clicked_corrections; 405 std::set<int> clicked_corrections;
381 406
382 // Track if specific buttons are included in an error page, for statistics. 407 // Track if specific buttons are included in an error page, for statistics.
383 bool reload_button_in_page; 408 bool reload_button_in_page;
384 bool load_stale_button_in_page; 409 bool load_stale_button_in_page;
385 410
386 // True if a page has completed loading, at which point it can receive 411 // True if a page has completed loading, at which point it can receive
387 // updates. 412 // updates.
388 bool is_finished_loading; 413 bool is_finished_loading;
414
415 // True if the auto-reload timer has fired and a reload is or has been in
416 // flight.
417 bool auto_reload_triggered;
389 }; 418 };
390 419
391 NetErrorHelperCore::NavigationCorrectionParams::NavigationCorrectionParams() { 420 NetErrorHelperCore::NavigationCorrectionParams::NavigationCorrectionParams() {
392 } 421 }
393 422
394 NetErrorHelperCore::NavigationCorrectionParams::~NavigationCorrectionParams() { 423 NetErrorHelperCore::NavigationCorrectionParams::~NavigationCorrectionParams() {
395 } 424 }
396 425
397 bool NetErrorHelperCore::IsReloadableError( 426 bool NetErrorHelperCore::IsReloadableError(
398 const NetErrorHelperCore::ErrorPageInfo& info) { 427 const NetErrorHelperCore::ErrorPageInfo& info) {
399 return info.error.domain.utf8() == net::kErrorDomain && 428 return info.error.domain.utf8() == net::kErrorDomain &&
400 info.error.reason != net::ERR_ABORTED && 429 info.error.reason != net::ERR_ABORTED &&
401 !info.was_failed_post; 430 !info.was_failed_post;
402 } 431 }
403 432
404 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) 433 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate)
405 : delegate_(delegate), 434 : delegate_(delegate),
406 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE), 435 last_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE),
407 auto_reload_enabled_(false), 436 auto_reload_enabled_(false),
408 auto_reload_timer_(new base::Timer(false, false)), 437 auto_reload_timer_(new base::Timer(false, false)),
438 auto_reload_paused_(false),
439 uncommitted_load_started_(false),
409 // TODO(ellyjones): Make online_ accurate at object creation. 440 // TODO(ellyjones): Make online_ accurate at object creation.
410 online_(true), 441 online_(true),
411 auto_reload_count_(0), 442 auto_reload_count_(0),
412 can_auto_reload_page_(false),
413 navigation_from_button_(NO_BUTTON) { 443 navigation_from_button_(NO_BUTTON) {
414 } 444 }
415 445
416 NetErrorHelperCore::~NetErrorHelperCore() { 446 NetErrorHelperCore::~NetErrorHelperCore() {
417 if (committed_error_page_info_ && can_auto_reload_page_) { 447 if (committed_error_page_info_ &&
418 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop", 448 committed_error_page_info_->auto_reload_triggered) {
419 -committed_error_page_info_->error.reason, 449 ReportAutoReloadFailure(committed_error_page_info_->error,
420 net::GetAllErrorCodesForUma()); 450 auto_reload_count_);
421 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_);
422 } 451 }
423 } 452 }
424 453
425 void NetErrorHelperCore::CancelPendingFetches() { 454 void NetErrorHelperCore::CancelPendingFetches() {
426 // Cancel loading the alternate error page, and prevent any pending error page 455 // Cancel loading the alternate error page, and prevent any pending error page
427 // load from starting a new error page load. Swapping in the error page when 456 // load from starting a new error page load. Swapping in the error page when
428 // it's finished loading could abort the navigation, otherwise. 457 // it's finished loading could abort the navigation, otherwise.
429 if (committed_error_page_info_ && can_auto_reload_page_) {
430 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop",
431 -committed_error_page_info_->error.reason,
432 net::GetAllErrorCodesForUma());
433 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_);
434 }
435 if (committed_error_page_info_) 458 if (committed_error_page_info_)
436 committed_error_page_info_->needs_load_navigation_corrections = false; 459 committed_error_page_info_->needs_load_navigation_corrections = false;
437 if (pending_error_page_info_) 460 if (pending_error_page_info_)
438 pending_error_page_info_->needs_load_navigation_corrections = false; 461 pending_error_page_info_->needs_load_navigation_corrections = false;
439 delegate_->CancelFetchNavigationCorrections(); 462 delegate_->CancelFetchNavigationCorrections();
440 auto_reload_timer_->Stop(); 463 auto_reload_timer_->Stop();
441 can_auto_reload_page_ = false; 464 auto_reload_paused_ = false;
442 } 465 }
443 466
444 void NetErrorHelperCore::OnStop() { 467 void NetErrorHelperCore::OnStop() {
468 if (committed_error_page_info_ &&
469 committed_error_page_info_->auto_reload_triggered) {
470 ReportAutoReloadFailure(committed_error_page_info_->error,
471 auto_reload_count_);
472 }
445 CancelPendingFetches(); 473 CancelPendingFetches();
474 uncommitted_load_started_ = false;
446 auto_reload_count_ = 0; 475 auto_reload_count_ = 0;
447 } 476 }
448 477
449 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { 478 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) {
450 if (frame_type != MAIN_FRAME) 479 if (frame_type != MAIN_FRAME)
451 return; 480 return;
452 481
482 uncommitted_load_started_ = true;
483
453 // If there's no pending error page information associated with the page load, 484 // If there's no pending error page information associated with the page load,
454 // or the new page is not an error page, then reset pending error page state. 485 // or the new page is not an error page, then reset pending error page state.
455 if (!pending_error_page_info_ || page_type != ERROR_PAGE) { 486 if (!pending_error_page_info_ || page_type != ERROR_PAGE)
456 CancelPendingFetches(); 487 CancelPendingFetches();
457 } else if (auto_reload_enabled_) {
458 // If an error load is starting, the resulting error page is autoreloadable.
459 can_auto_reload_page_ = IsReloadableError(*pending_error_page_info_);
460 }
461 } 488 }
462 489
463 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { 490 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type, const GURL& url) {
464 if (frame_type != MAIN_FRAME) 491 if (frame_type != MAIN_FRAME)
465 return; 492 return;
466 493
494 // uncommitted_load_started_ could already be false, since RenderFrameImpl
495 // calls OnCommitLoad once for each in-page navigation (like a fragment
496 // change) with no corresponding OnStartLoad.
497 uncommitted_load_started_ = false;
498
467 // Track if an error occurred due to a page button press. 499 // Track if an error occurred due to a page button press.
468 // This isn't perfect; if (for instance), the server is slow responding 500 // This isn't perfect; if (for instance), the server is slow responding
469 // to a request generated from the page reload button, and the user hits 501 // to a request generated from the page reload button, and the user hits
470 // the browser reload button, this code will still believe the 502 // the browser reload button, this code will still believe the
471 // result is from the page reload button. 503 // result is from the page reload button.
472 if (committed_error_page_info_ && pending_error_page_info_ && 504 if (committed_error_page_info_ && pending_error_page_info_ &&
473 navigation_from_button_ != NO_BUTTON && 505 navigation_from_button_ != NO_BUTTON &&
474 committed_error_page_info_->error.unreachableURL == 506 committed_error_page_info_->error.unreachableURL ==
475 pending_error_page_info_->error.unreachableURL) { 507 pending_error_page_info_->error.unreachableURL) {
476 DCHECK(navigation_from_button_ == RELOAD_BUTTON || 508 DCHECK(navigation_from_button_ == RELOAD_BUTTON ||
477 navigation_from_button_ == LOAD_STALE_BUTTON); 509 navigation_from_button_ == LOAD_STALE_BUTTON);
478 chrome_common_net::RecordEvent( 510 chrome_common_net::RecordEvent(
479 navigation_from_button_ == RELOAD_BUTTON ? 511 navigation_from_button_ == RELOAD_BUTTON ?
480 chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR : 512 chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR :
481 chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_ERROR); 513 chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_ERROR);
482 } 514 }
483 navigation_from_button_ = NO_BUTTON; 515 navigation_from_button_ = NO_BUTTON;
484 516
485 if (committed_error_page_info_ && !pending_error_page_info_ && 517 if (committed_error_page_info_ && !pending_error_page_info_ &&
486 can_auto_reload_page_) { 518 committed_error_page_info_->auto_reload_triggered) {
487 int reason = committed_error_page_info_->error.reason; 519 const blink::WebURLError& error = committed_error_page_info_->error;
488 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess", 520 const GURL& error_url = error.unreachableURL;
489 -reason, 521 if (url == error_url)
490 net::GetAllErrorCodesForUma()); 522 ReportAutoReloadSuccess(error, auto_reload_count_);
491 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", auto_reload_count_); 523 else if (url != GURL(content::kUnreachableWebDataURL))
492 if (auto_reload_count_ == 1) { 524 ReportAutoReloadFailure(error, auto_reload_count_);
493 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess",
494 -reason,
495 net::GetAllErrorCodesForUma());
496 }
497 } 525 }
498 526
499 committed_error_page_info_.reset(pending_error_page_info_.release()); 527 committed_error_page_info_.reset(pending_error_page_info_.release());
500 } 528 }
501 529
502 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { 530 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
503 if (frame_type != MAIN_FRAME) 531 if (frame_type != MAIN_FRAME)
504 return; 532 return;
505 533
506 if (!committed_error_page_info_) { 534 if (!committed_error_page_info_) {
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 void NetErrorHelperCore::Reload() { 755 void NetErrorHelperCore::Reload() {
728 if (!committed_error_page_info_) { 756 if (!committed_error_page_info_) {
729 return; 757 return;
730 } 758 }
731 delegate_->ReloadPage(); 759 delegate_->ReloadPage();
732 } 760 }
733 761
734 bool NetErrorHelperCore::MaybeStartAutoReloadTimer() { 762 bool NetErrorHelperCore::MaybeStartAutoReloadTimer() {
735 if (!committed_error_page_info_ || 763 if (!committed_error_page_info_ ||
736 !committed_error_page_info_->is_finished_loading || 764 !committed_error_page_info_->is_finished_loading ||
737 !can_auto_reload_page_ || 765 pending_error_page_info_ ||
738 pending_error_page_info_) { 766 uncommitted_load_started_) {
739 return false; 767 return false;
740 } 768 }
741 769
742 DCHECK(IsReloadableError(*committed_error_page_info_));
743
744 if (!online_)
745 return false;
746
747 StartAutoReloadTimer(); 770 StartAutoReloadTimer();
748 return true; 771 return true;
749 } 772 }
750 773
751 void NetErrorHelperCore::StartAutoReloadTimer() { 774 void NetErrorHelperCore::StartAutoReloadTimer() {
752 DCHECK(committed_error_page_info_); 775 DCHECK(committed_error_page_info_);
753 DCHECK(can_auto_reload_page_); 776 DCHECK(IsReloadableError(*committed_error_page_info_));
777
778 committed_error_page_info_->auto_reload_triggered = true;
779
780 if (!online_) {
781 auto_reload_paused_ = true;
782 return;
783 }
784
785 auto_reload_paused_ = false;
754 base::TimeDelta delay = GetAutoReloadTime(auto_reload_count_); 786 base::TimeDelta delay = GetAutoReloadTime(auto_reload_count_);
755 auto_reload_timer_->Stop(); 787 auto_reload_timer_->Stop();
756 auto_reload_timer_->Start(FROM_HERE, delay, 788 auto_reload_timer_->Start(FROM_HERE, delay,
757 base::Bind(&NetErrorHelperCore::AutoReloadTimerFired, 789 base::Bind(&NetErrorHelperCore::AutoReloadTimerFired,
758 base::Unretained(this))); 790 base::Unretained(this)));
759 } 791 }
760 792
761 void NetErrorHelperCore::AutoReloadTimerFired() { 793 void NetErrorHelperCore::AutoReloadTimerFired() {
762 auto_reload_count_++; 794 auto_reload_count_++;
763 Reload(); 795 Reload();
764 } 796 }
765 797
766 void NetErrorHelperCore::NetworkStateChanged(bool online) { 798 void NetErrorHelperCore::NetworkStateChanged(bool online) {
799 bool was_online = online_;
767 online_ = online; 800 online_ = online;
768 if (auto_reload_timer_->IsRunning()) { 801 if (!was_online && online) {
769 DCHECK(committed_error_page_info_); 802 // Transitioning offline -> online
770 // If there's an existing timer running, stop it and reset the retry count. 803 if (auto_reload_paused_)
771 auto_reload_timer_->Stop(); 804 MaybeStartAutoReloadTimer();
772 auto_reload_count_ = 0; 805 } else if (was_online && !online) {
806 // Transitioning online -> offline
807 if (auto_reload_timer_->IsRunning()) {
808 DCHECK(committed_error_page_info_);
809 DCHECK(!auto_reload_paused_);
810 DCHECK(committed_error_page_info_->auto_reload_triggered);
811 auto_reload_timer_->Stop();
812 auto_reload_count_ = 0;
813 auto_reload_paused_ = true;
814 }
773 } 815 }
774
775 // If the network state changed to online, maybe start auto-reloading again.
776 if (online)
777 MaybeStartAutoReloadTimer();
778 } 816 }
779 817
780 bool NetErrorHelperCore::ShouldSuppressErrorPage(FrameType frame_type, 818 bool NetErrorHelperCore::ShouldSuppressErrorPage(FrameType frame_type,
781 const GURL& url) { 819 const GURL& url) {
782 // Don't suppress child frame errors. 820 // Don't suppress child frame errors.
783 if (frame_type != MAIN_FRAME) 821 if (frame_type != MAIN_FRAME)
784 return false; 822 return false;
785 823
786 // If |auto_reload_timer_| is still running, this error page isn't from an 824 if (!auto_reload_enabled_)
787 // auto reload.
788 if (auto_reload_timer_->IsRunning())
789 return false; 825 return false;
790 826
791 // If there's no committed error page, this error page wasn't from an auto 827 // If there's no committed error page, this error page wasn't from an auto
792 // reload. 828 // reload.
793 if (!committed_error_page_info_ || !can_auto_reload_page_) 829 if (!committed_error_page_info_)
794 return false; 830 return false;
795 831
832 // If the error page wasn't reloadable, display it.
833 if (!IsReloadableError(*committed_error_page_info_))
834 return false;
835
836 // If |auto_reload_timer_| is still running or is paused, this error page
837 // isn't from an auto reload.
838 if (auto_reload_timer_->IsRunning() || auto_reload_paused_)
839 return false;
840
841 // If the error page was reloadable, and the timer isn't running or paused, an
842 // auto-reload has already been triggered.
843 DCHECK(committed_error_page_info_->auto_reload_triggered);
844
796 GURL error_url = committed_error_page_info_->error.unreachableURL; 845 GURL error_url = committed_error_page_info_->error.unreachableURL;
797 // TODO(ellyjones): also plumb the error code down to CCRC and check that 846 // TODO(ellyjones): also plumb the error code down to CCRC and check that
798 if (error_url != url) 847 if (error_url != url)
799 return false; 848 return false;
800 849
850 // Suppressed an error-page load; the previous uncommitted load was the error
851 // page load starting, so forget about it.
852 uncommitted_load_started_ = false;
853
801 // The first iteration of the timer is started by OnFinishLoad calling 854 // The first iteration of the timer is started by OnFinishLoad calling
802 // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are 855 // MaybeStartAutoReloadTimer, but since error pages for subsequent loads are
803 // suppressed in this function, subsequent iterations of the timer have to be 856 // suppressed in this function, subsequent iterations of the timer have to be
804 // started here. 857 // started here.
805 MaybeStartAutoReloadTimer(); 858 MaybeStartAutoReloadTimer();
806 return true; 859 return true;
807 } 860 }
808 861
809 void NetErrorHelperCore::ExecuteButtonPress(Button button) { 862 void NetErrorHelperCore::ExecuteButtonPress(Button button) {
810 switch (button) { 863 switch (button) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 std::string request_body = CreateClickTrackingUrlRequestBody( 914 std::string request_body = CreateClickTrackingUrlRequestBody(
862 committed_error_page_info_->error, 915 committed_error_page_info_->error,
863 *committed_error_page_info_->navigation_correction_params, 916 *committed_error_page_info_->navigation_correction_params,
864 *response, 917 *response,
865 *response->corrections[tracking_id]); 918 *response->corrections[tracking_id]);
866 delegate_->SendTrackingRequest( 919 delegate_->SendTrackingRequest(
867 committed_error_page_info_->navigation_correction_params->url, 920 committed_error_page_info_->navigation_correction_params->url,
868 request_body); 921 request_body);
869 } 922 }
870 923
OLDNEW
« no previous file with comments | « chrome/renderer/net/net_error_helper_core.h ('k') | chrome/renderer/net/net_error_helper_core_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698