When the auto-reload experiment is enabled ("enable-offline-auto-reload"), if a browser tab loads an error page, and the error seems transient, the renderer process starts attempting to automatically reload the tab's contents with exponential backoff.

To NetErrorHelperCore, add a new delegate method: ReloadPage(), which kicks off
a reload of the page in the observed frame. Add a new class MockableOneShotTimer
which provides a mockable interface to the standard base::OneShotTimer and is
used in NetErrorHelperCore for the autoreload timer.  Add an implementation of
MockableOneShotTimer.
    
Add new member variables 'auto_reload_count_', 'auto_reload_pending_', and
'auto_reload_enabled_' to NetErrorHelperCore. The first tracks how many attempts
we have made to auto-reload; the second tracks whether we should be attempting
auto-reloads (i.e., the last loaded page was an error, and the user did not hit
'Stop' since that load); the last controls whether autoreload is enabled or not
and defaults to false.
    
The autoreload logic itself exists in
NetErrorHelperCore::{AutoReload,MaybeStartAutoReloadTimer,StartAutoReloadTimer}.
StartAutoReloadTimer sets a timer (auto_reload_timer_) which calls AutoReload
when it fires, and AutoReload starts a fetch of the error URL. The timer is
started with a successively larger interval at each successive call to
StartAutoReload() to implement exponential backoff. The auto-reload count is
reset (thus restarting the backoff) when we get a non-reloadable error like an
ERR_ABORTED or when a non-error page loads successfully. Any pending auto-reload
attempts stop (but the timer is not reset) if the user manually presses 'stop'
or a cross-process navigation starts (handled in NetErrorHelperCore::OnStop).
MaybeStartAutoReloadTimer is the real entry point for auto-reload; it starts
auto-reload if the last load was a reloadable error page, the browser is online,
and the user hasn't stopped the error page.
    
Also, extend the existing hook in
ChromeContentRendererClient::ShouldSuppressErrorPage to call
NetErrorHelper::ShouldSuppressErrorPage, which plumbs the request through to
NetErrorHelperCore.
    
Right now, if there are many tabs displaying error pages, the code in
NetworkStateChange() can cause a "reload storm", in which dozens or even
hundreds of auto-reload attempts start at the same time, possibly saturating the
network. Our current design for resolving this involves a ResourceThrottle in
the browser process to throttle individual tab loading, but design work is still
ongoing.
    
There are unit tests in NetErrorHelperCoreTest covering the various behaviors of
auto-reload, and helper code and a mock MockableOneShotTimer implementation
added to NetErrorHelperCoreTest. There is a browser test in
ErrorPageAutoReloadTest.
    
TODO: solve the "reload storm" issue.
    
TEST=unit,browser,trybot
BUG=308233

Review URL: https://codereview.chromium.org/136203009

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@257254 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index c78cf8c3..83190b3 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1580,6 +1580,7 @@
       switches::kEnableNaClDebug,
       switches::kEnableNaClNonSfiMode,
       switches::kEnableNetBenchmarking,
+      switches::kEnableOfflineAutoReload,
       switches::kEnableStreamlinedHostedApps,
       switches::kEnableWatchdog,
       switches::kMemoryProfiling,