12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/net/net_error_tab_helper.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/logging.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/io_thread.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/net/dns_probe_service.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/net/net_error_info.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/render_messages.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatus;
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing chrome_common_net::DnsProbeStatusToString;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserContext;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::PageTransition;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::RenderViewHost;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContents;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContentsObserver;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DEFINE_WEB_CONTENTS_USER_DATA_KEY(chrome_browser_net::NetErrorTabHelper);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chrome_browser_net {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static NetErrorTabHelper::TestingState testing_state_ =
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NetErrorTabHelper::TESTING_DEFAULT;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns whether |net_error| is a DNS-related error (and therefore whether
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the tab helper should start a DNS probe after receiving it.)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsDnsError(int net_error) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return net_error == net::ERR_NAME_NOT_RESOLVED ||
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         net_error == net::ERR_NAME_RESOLUTION_FAILED;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OnDnsProbeFinishedOnIOThread(
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Callback<void(DnsProbeStatus)>& callback,
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DnsProbeStatus result) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(callback, result));
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Can only access g_browser_process->io_thread() from the browser thread,
587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// so have to pass it in to the callback instead of dereferencing it here.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StartDnsProbeOnIOThread(
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Callback<void(DnsProbeStatus)>& callback,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IOThread* io_thread) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DnsProbeService* probe_service =
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      io_thread->globals()->dns_probe_service.get();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  probe_service->ProbeDns(base::Bind(&OnDnsProbeFinishedOnIOThread, callback));
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetErrorTabHelper::~NetErrorTabHelper() {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetErrorTabHelper::set_state_for_testing(TestingState state) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing_state_ = state;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid NetErrorTabHelper::DidStartNavigationToPendingEntry(
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& url,
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    content::NavigationController::ReloadType reload_type) {
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!is_error_page_)
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Only record reloads.
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (reload_type != content::NavigationController::NO_RELOAD) {
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    chrome_common_net::RecordEvent(
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        chrome_common_net::NETWORK_ERROR_PAGE_BROWSER_INITIATED_RELOAD);
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetErrorTabHelper::DidStartProvisionalLoadForFrame(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 frame_id,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 parent_frame_id,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_main_frame,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& validated_url,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_error_page,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_iframe_srcdoc,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderViewHost* render_view_host) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!is_main_frame)
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  is_error_page_ = is_error_page;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetErrorTabHelper::DidCommitProvisionalLoadForFrame(
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 frame_id,
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& frame_unique_name,
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_main_frame,
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PageTransition transition_type,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderViewHost* render_view_host) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!is_main_frame)
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Resend status every time an error page commits; this is somewhat spammy,
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // but ensures that the status will make it to the real error page, even if
1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // the link doctor loads a blank intermediate page or the tab switches
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // renderer processes.
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (is_error_page_ && dns_error_active_) {
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dns_error_page_committed_ = true;
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DVLOG(1) << "Committed error page; resending status.";
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SendInfo();
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dns_error_active_ = false;
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dns_error_page_committed_ = false;
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetErrorTabHelper::DidFailProvisionalLoad(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int64 frame_id,
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& frame_unique_name,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_main_frame,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& validated_url,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int error_code,
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& error_description,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RenderViewHost* render_view_host) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!is_main_frame)
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (IsDnsError(error_code)) {
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dns_error_active_ = true;
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    OnMainFrameDnsError();
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NetErrorTabHelper::NetErrorTabHelper(WebContents* contents)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : WebContentsObserver(contents),
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this),
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      is_error_page_(false),
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      dns_error_active_(false),
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      dns_error_page_committed_(false),
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      dns_probe_status_(chrome_common_net::DNS_PROBE_POSSIBLE) {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If this helper is under test, it won't have a WebContents.
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (contents)
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    InitializePref(contents);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NetErrorTabHelper::OnMainFrameDnsError() {
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (ProbesAllowed()) {
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Don't start more than one probe at a time.
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (dns_probe_status_ != chrome_common_net::DNS_PROBE_STARTED) {
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      StartDnsProbe();
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      dns_probe_status_ = chrome_common_net::DNS_PROBE_STARTED;
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dns_probe_status_ = chrome_common_net::DNS_PROBE_NOT_RUN;
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NetErrorTabHelper::StartDnsProbe() {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(dns_error_active_);
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_NE(chrome_common_net::DNS_PROBE_STARTED, dns_probe_status_);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DVLOG(1) << "Starting DNS probe.";
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  BrowserThread::PostTask(
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      BrowserThread::IO,
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      FROM_HERE,
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&StartDnsProbeOnIOThread,
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Bind(&NetErrorTabHelper::OnDnsProbeFinished,
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            weak_factory_.GetWeakPtr()),
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 g_browser_process->io_thread()));
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NetErrorTabHelper::OnDnsProbeFinished(DnsProbeStatus result) {
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_EQ(chrome_common_net::DNS_PROBE_STARTED, dns_probe_status_);
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(chrome_common_net::DnsProbeStatusIsFinished(result));
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DVLOG(1) << "Finished DNS probe with result "
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch           << DnsProbeStatusToString(result) << ".";
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  dns_probe_status_ = result;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (dns_error_page_committed_)
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SendInfo();
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NetErrorTabHelper::InitializePref(WebContents* contents) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(contents);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserContext* browser_context = contents->GetBrowserContext();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile = Profile::FromBrowserContext(browser_context);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resolve_errors_with_web_service_.Init(
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      prefs::kAlternateErrorPagesEnabled,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile->GetPrefs());
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NetErrorTabHelper::ProbesAllowed() const {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (testing_state_ != TESTING_DEFAULT)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return testing_state_ == TESTING_FORCE_ENABLED;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(ttuttle): Disable on mobile?
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return *resolve_errors_with_web_service_;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NetErrorTabHelper::SendInfo() {
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_NE(chrome_common_net::DNS_PROBE_POSSIBLE, dns_probe_status_);
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(dns_error_page_committed_);
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DVLOG(1) << "Sending status " << DnsProbeStatusToString(dns_probe_status_);
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::RenderFrameHost* rfh = web_contents()->GetMainFrame();
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rfh->Send(new ChromeViewMsg_NetErrorInfo(rfh->GetRoutingID(),
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           dns_probe_status_));
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!dns_probe_status_snoop_callback_.is_null())
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    dns_probe_status_snoop_callback_.Run(dns_probe_status_);
2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chrome_browser_net
244