Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser/net/net_error_tab_helper.h" | 5 #include "chrome/browser/net/net_error_tab_helper.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| 11 #include "chrome/browser/io_thread.h" | 11 #include "chrome/browser/io_thread.h" |
| 12 #include "chrome/browser/net/dns_probe_service.h" | 12 #include "chrome/browser/net/dns_probe_service.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/common/net/net_error_info.h" | 14 #include "chrome/common/net/net_error_info.h" |
| 15 #include "chrome/common/pref_names.h" | 15 #include "chrome/common/pref_names.h" |
| 16 #include "chrome/common/render_messages.h" | 16 #include "chrome/common/render_messages.h" |
| 17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 19 | 19 |
| 20 using base::FieldTrialList; | 20 using base::FieldTrialList; |
| 21 using chrome_common_net::DnsProbeResult; | 21 using chrome_common_net::DnsProbeStatus; |
| 22 using content::BrowserContext; | 22 using content::BrowserContext; |
| 23 using content::BrowserThread; | 23 using content::BrowserThread; |
| 24 using content::PageTransition; | 24 using content::PageTransition; |
| 25 using content::RenderViewHost; | 25 using content::RenderViewHost; |
| 26 using content::WebContents; | 26 using content::WebContents; |
| 27 using content::WebContentsObserver; | 27 using content::WebContentsObserver; |
| 28 | 28 |
| 29 DEFINE_WEB_CONTENTS_USER_DATA_KEY(chrome_browser_net::NetErrorTabHelper); | 29 DEFINE_WEB_CONTENTS_USER_DATA_KEY(chrome_browser_net::NetErrorTabHelper); |
| 30 | 30 |
| 31 namespace chrome_browser_net { | 31 namespace chrome_browser_net { |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 const char kDnsProbeFieldTrialName[] = "DnsProbe-Enable"; | |
| 36 const char kDnsProbeFieldTrialEnableGroupName[] = "enable"; | |
| 37 | |
| 38 static NetErrorTabHelper::TestingState testing_state_ = | 35 static NetErrorTabHelper::TestingState testing_state_ = |
| 39 NetErrorTabHelper::TESTING_DEFAULT; | 36 NetErrorTabHelper::TESTING_DEFAULT; |
| 40 | 37 |
| 41 // Returns whether |net_error| is a DNS-related error (and therefore whether | 38 // Returns whether |net_error| is a DNS-related error (and therefore whether |
| 42 // the tab helper should start a DNS probe after receiving it.) | 39 // the tab helper should start a DNS probe after receiving it.) |
| 43 bool IsDnsError(int net_error) { | 40 bool IsDnsError(int net_error) { |
| 44 return net_error == net::ERR_NAME_NOT_RESOLVED || | 41 return net_error == net::ERR_NAME_NOT_RESOLVED || |
| 45 net_error == net::ERR_NAME_RESOLUTION_FAILED; | 42 net_error == net::ERR_NAME_RESOLUTION_FAILED; |
| 46 } | 43 } |
| 47 | 44 |
| 48 bool GetEnabledByTrial() { | |
| 49 return (FieldTrialList::FindFullName(kDnsProbeFieldTrialName) | |
| 50 == kDnsProbeFieldTrialEnableGroupName); | |
| 51 } | |
| 52 | |
| 53 NetErrorTracker::FrameType GetFrameType(bool is_main_frame) { | 45 NetErrorTracker::FrameType GetFrameType(bool is_main_frame) { |
| 54 return is_main_frame ? NetErrorTracker::FRAME_MAIN | 46 return is_main_frame ? NetErrorTracker::FRAME_MAIN |
| 55 : NetErrorTracker::FRAME_SUB; | 47 : NetErrorTracker::FRAME_SUB; |
| 56 } | 48 } |
| 57 | 49 |
| 58 NetErrorTracker::PageType GetPageType(bool is_error_page) { | 50 NetErrorTracker::PageType GetPageType(bool is_error_page) { |
| 59 return is_error_page ? NetErrorTracker::PAGE_ERROR | 51 return is_error_page ? NetErrorTracker::PAGE_ERROR |
| 60 : NetErrorTracker::PAGE_NORMAL; | 52 : NetErrorTracker::PAGE_NORMAL; |
| 61 } | 53 } |
| 62 | 54 |
| 63 NetErrorTracker::ErrorType GetErrorType(int net_error) { | 55 NetErrorTracker::ErrorType GetErrorType(int net_error) { |
| 64 return IsDnsError(net_error) ? NetErrorTracker::ERROR_DNS | 56 return IsDnsError(net_error) ? NetErrorTracker::ERROR_DNS |
| 65 : NetErrorTracker::ERROR_OTHER; | 57 : NetErrorTracker::ERROR_OTHER; |
| 66 } | 58 } |
| 67 | 59 |
| 68 void OnDnsProbeFinishedOnIOThread( | 60 void OnDnsProbeFinishedOnIOThread( |
| 69 const base::Callback<void(DnsProbeResult)>& callback, | 61 const base::Callback<void(DnsProbeStatus)>& callback, |
| 70 DnsProbeResult result) { | 62 DnsProbeStatus result) { |
| 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 72 | 64 |
| 73 DVLOG(1) << "DNS probe finished with result " << result; | |
| 74 | |
| 75 BrowserThread::PostTask( | 65 BrowserThread::PostTask( |
| 76 BrowserThread::UI, | 66 BrowserThread::UI, |
| 77 FROM_HERE, | 67 FROM_HERE, |
| 78 base::Bind(callback, result)); | 68 base::Bind(callback, result)); |
| 79 } | 69 } |
| 80 | 70 |
| 81 // We can only access g_browser_process->io_thread() from the browser thread, | 71 // We can only access g_browser_process->io_thread() from the browser thread, |
| 82 // so we have to pass it in to the callback instead of dereferencing it here. | 72 // so we have to pass it in to the callback instead of dereferencing it here. |
| 83 void StartDnsProbeOnIOThread( | 73 void StartDnsProbeOnIOThread( |
| 84 const base::Callback<void(DnsProbeResult)>& callback, | 74 const base::Callback<void(DnsProbeStatus)>& callback, |
| 85 IOThread* io_thread) { | 75 IOThread* io_thread) { |
| 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 87 | 77 |
| 88 DVLOG(1) << "Starting DNS probe"; | |
| 89 | |
| 90 DnsProbeService* probe_service = | 78 DnsProbeService* probe_service = |
| 91 io_thread->globals()->dns_probe_service.get(); | 79 io_thread->globals()->dns_probe_service.get(); |
| 92 | 80 |
| 93 probe_service->ProbeDns(base::Bind(&OnDnsProbeFinishedOnIOThread, callback)); | 81 probe_service->ProbeDns(base::Bind(&OnDnsProbeFinishedOnIOThread, callback)); |
| 94 } | 82 } |
| 95 | 83 |
| 96 } // namespace | 84 } // namespace |
| 97 | 85 |
| 98 NetErrorTabHelper::~NetErrorTabHelper() { | 86 NetErrorTabHelper::~NetErrorTabHelper() { |
| 99 } | 87 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 } | 140 } |
| 153 | 141 |
| 154 NetErrorTabHelper::NetErrorTabHelper(WebContents* contents) | 142 NetErrorTabHelper::NetErrorTabHelper(WebContents* contents) |
| 155 : WebContentsObserver(contents), | 143 : WebContentsObserver(contents), |
| 156 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 144 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 157 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_( | 145 ALLOW_THIS_IN_INITIALIZER_LIST(tracker_( |
| 158 base::Bind(&NetErrorTabHelper::TrackerCallback, | 146 base::Bind(&NetErrorTabHelper::TrackerCallback, |
| 159 weak_factory_.GetWeakPtr()))), | 147 weak_factory_.GetWeakPtr()))), |
| 160 dns_error_page_state_(NetErrorTracker::DNS_ERROR_PAGE_NONE), | 148 dns_error_page_state_(NetErrorTracker::DNS_ERROR_PAGE_NONE), |
| 161 dns_probe_state_(DNS_PROBE_NONE), | 149 dns_probe_state_(DNS_PROBE_NONE), |
| 162 enabled_by_trial_(GetEnabledByTrial()) { | 150 enabled_by_trial_(chrome_common_net::DnsProbesEnabledByFieldTrial()) { |
| 163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 164 | 152 |
| 165 InitializePref(contents); | 153 InitializePref(contents); |
| 166 } | 154 } |
| 167 | 155 |
| 168 void NetErrorTabHelper::TrackerCallback( | 156 void NetErrorTabHelper::TrackerCallback( |
| 169 NetErrorTracker::DnsErrorPageState state) { | 157 NetErrorTracker::DnsErrorPageState tracker_state) { |
| 170 dns_error_page_state_ = state; | 158 DVLOG(1) << "Browser in tracker state " << tracker_state << "."; |
| 159 | |
| 160 dns_error_page_state_ = tracker_state; | |
| 171 | 161 |
| 172 MaybePostStartDnsProbeTask(); | 162 MaybePostStartDnsProbeTask(); |
| 173 MaybeSendInfo(); | 163 MaybeSendStatus(); |
| 174 } | 164 } |
| 175 | 165 |
| 176 void NetErrorTabHelper::MaybePostStartDnsProbeTask() { | 166 void NetErrorTabHelper::MaybePostStartDnsProbeTask() { |
| 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 178 | 168 |
| 179 if (dns_error_page_state_ != NetErrorTracker::DNS_ERROR_PAGE_NONE && | 169 if (dns_error_page_state_ == NetErrorTracker::DNS_ERROR_PAGE_NONE || |
| 180 dns_probe_state_ != DNS_PROBE_STARTED && | 170 dns_probe_state_ != DNS_PROBE_NONE || |
| 181 ProbesAllowed()) { | 171 !ProbesAllowed()) { |
| 182 BrowserThread::PostTask( | 172 return; |
| 183 BrowserThread::IO, | |
| 184 FROM_HERE, | |
| 185 base::Bind(&StartDnsProbeOnIOThread, | |
| 186 base::Bind(&NetErrorTabHelper::OnDnsProbeFinished, | |
| 187 weak_factory_.GetWeakPtr()), | |
| 188 g_browser_process->io_thread())); | |
| 189 dns_probe_state_ = DNS_PROBE_STARTED; | |
| 190 } | 173 } |
| 174 | |
| 175 DVLOG(1) << "Starting DNS probe."; | |
| 176 | |
| 177 BrowserThread::PostTask( | |
| 178 BrowserThread::IO, | |
| 179 FROM_HERE, | |
| 180 base::Bind(&StartDnsProbeOnIOThread, | |
| 181 base::Bind(&NetErrorTabHelper::OnDnsProbeFinished, | |
| 182 weak_factory_.GetWeakPtr()), | |
| 183 g_browser_process->io_thread())); | |
| 184 dns_probe_state_ = DNS_PROBE_STARTED; | |
| 191 } | 185 } |
| 192 | 186 |
| 193 void NetErrorTabHelper::OnDnsProbeFinished(DnsProbeResult result) { | 187 void NetErrorTabHelper::OnDnsProbeFinished(DnsProbeStatus result) { |
| 194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 188 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 195 DCHECK_EQ(DNS_PROBE_STARTED, dns_probe_state_); | 189 DCHECK_EQ(DNS_PROBE_STARTED, dns_probe_state_); |
| 196 | 190 |
| 191 DVLOG(1) << "Finished DNS probe with result " << result << "."; | |
| 192 | |
| 197 dns_probe_result_ = result; | 193 dns_probe_result_ = result; |
|
mmenke
2013/04/10 16:56:58
I don't think we gain anything from having |dns_pr
Deprecated (see juliatuttle)
2013/04/10 23:42:32
The state machine is still complicated. We're sim
| |
| 198 dns_probe_state_ = DNS_PROBE_FINISHED; | 194 dns_probe_state_ = DNS_PROBE_FINISHED; |
| 199 | 195 |
| 200 MaybeSendInfo(); | 196 MaybeSendStatus(); |
| 201 } | 197 } |
| 202 | 198 |
| 203 void NetErrorTabHelper::MaybeSendInfo() { | 199 void NetErrorTabHelper::MaybeSendStatus() { |
| 204 if (dns_error_page_state_ == NetErrorTracker::DNS_ERROR_PAGE_LOADED && | 200 if (dns_error_page_state_ != NetErrorTracker::DNS_ERROR_PAGE_LOADED) |
| 205 dns_probe_state_ == DNS_PROBE_FINISHED) { | 201 return; |
| 206 DVLOG(1) << "Sending result " << dns_probe_result_ << " to renderer"; | 202 |
| 207 Send(new ChromeViewMsg_NetErrorInfo(routing_id(), dns_probe_result_)); | 203 switch (dns_probe_state_) { |
| 204 case DNS_PROBE_STARTED: | |
| 205 DVLOG(1) << "Browser sending STARTED."; | |
| 206 SendInfo(chrome_common_net::DNS_PROBE_STARTED); | |
| 207 break; | |
| 208 | |
| 209 case DNS_PROBE_FINISHED: | |
| 210 DVLOG(1) << "Browser sending result " << dns_probe_result_; | |
| 211 SendInfo(dns_probe_result_); | |
| 208 dns_probe_state_ = DNS_PROBE_NONE; | 212 dns_probe_state_ = DNS_PROBE_NONE; |
| 213 break; | |
| 214 | |
| 215 case DNS_PROBE_NONE: | |
| 216 DVLOG(1) << "Browser sending NOT_RUN."; | |
| 217 SendInfo(chrome_common_net::DNS_PROBE_NOT_RUN); | |
|
mmenke
2013/04/10 16:56:58
Think sending this on all tracker events is a bit
Deprecated (see juliatuttle)
2013/04/10 23:42:32
We don't. We only send it if the page has just lo
| |
| 218 break; | |
| 219 | |
| 220 default: | |
| 221 NOTREACHED(); | |
| 209 } | 222 } |
| 210 } | 223 } |
| 211 | 224 |
| 225 void NetErrorTabHelper::SendInfo( | |
| 226 DnsProbeStatus status) { | |
| 227 Send(new ChromeViewMsg_NetErrorInfo(routing_id(), status)); | |
| 228 } | |
| 229 | |
| 212 void NetErrorTabHelper::InitializePref(WebContents* contents) { | 230 void NetErrorTabHelper::InitializePref(WebContents* contents) { |
| 213 DCHECK(contents); | 231 DCHECK(contents); |
| 214 | 232 |
| 215 BrowserContext* browser_context = contents->GetBrowserContext(); | 233 BrowserContext* browser_context = contents->GetBrowserContext(); |
| 216 Profile* profile = Profile::FromBrowserContext(browser_context); | 234 Profile* profile = Profile::FromBrowserContext(browser_context); |
| 217 resolve_errors_with_web_service_.Init( | 235 resolve_errors_with_web_service_.Init( |
| 218 prefs::kAlternateErrorPagesEnabled, | 236 prefs::kAlternateErrorPagesEnabled, |
| 219 profile->GetPrefs()); | 237 profile->GetPrefs()); |
| 220 } | 238 } |
| 221 | 239 |
| 222 bool NetErrorTabHelper::ProbesAllowed() const { | 240 bool NetErrorTabHelper::ProbesAllowed() const { |
| 223 if (testing_state_ != TESTING_DEFAULT) | 241 if (testing_state_ != TESTING_DEFAULT) |
| 224 return testing_state_ == TESTING_FORCE_ENABLED; | 242 return testing_state_ == TESTING_FORCE_ENABLED; |
| 225 | 243 |
| 226 // TODO(ttuttle): Disable on mobile? | 244 // TODO(ttuttle): Disable on mobile? |
| 227 return enabled_by_trial_ && *resolve_errors_with_web_service_; | 245 return enabled_by_trial_ && *resolve_errors_with_web_service_; |
| 228 } | 246 } |
| 229 | 247 |
| 230 } // namespace chrome_browser_net | 248 } // namespace chrome_browser_net |
| OLD | NEW |