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 |