Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 | 249 |
| 250 } // namespace | 250 } // namespace |
| 251 | 251 |
| 252 struct NetErrorHelperCore::ErrorPageInfo { | 252 struct NetErrorHelperCore::ErrorPageInfo { |
| 253 ErrorPageInfo(blink::WebURLError error, bool was_failed_post) | 253 ErrorPageInfo(blink::WebURLError error, bool was_failed_post) |
| 254 : error(error), | 254 : error(error), |
| 255 was_failed_post(was_failed_post), | 255 was_failed_post(was_failed_post), |
| 256 needs_dns_updates(false), | 256 needs_dns_updates(false), |
| 257 reload_button_in_page(false), | 257 reload_button_in_page(false), |
| 258 load_stale_button_in_page(false), | 258 load_stale_button_in_page(false), |
| 259 is_finished_loading(false) { | 259 is_finished_loading(false), |
| 260 is_auto_reloading(false) { | |
| 260 } | 261 } |
| 261 | 262 |
| 262 // Information about the failed page load. | 263 // Information about the failed page load. |
| 263 blink::WebURLError error; | 264 blink::WebURLError error; |
| 264 bool was_failed_post; | 265 bool was_failed_post; |
| 265 | 266 |
| 266 // Information about the status of the error page. | 267 // Information about the status of the error page. |
| 267 | 268 |
| 268 // True if a page is a DNS error page and has not yet received a final DNS | 269 // True if a page is a DNS error page and has not yet received a final DNS |
| 269 // probe status. | 270 // probe status. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 281 // the blank page is loading, to get rid of these. | 282 // the blank page is loading, to get rid of these. |
| 282 std::string navigation_correction_request_body; | 283 std::string navigation_correction_request_body; |
| 283 | 284 |
| 284 // Track if specific buttons are included in an error page, for statistics. | 285 // Track if specific buttons are included in an error page, for statistics. |
| 285 bool reload_button_in_page; | 286 bool reload_button_in_page; |
| 286 bool load_stale_button_in_page; | 287 bool load_stale_button_in_page; |
| 287 | 288 |
| 288 // True if a page has completed loading, at which point it can receive | 289 // True if a page has completed loading, at which point it can receive |
| 289 // updates. | 290 // updates. |
| 290 bool is_finished_loading; | 291 bool is_finished_loading; |
| 292 | |
| 293 // True if the page is being auto-reloaded. | |
| 294 bool is_auto_reloading; | |
|
mmenke
2014/04/25 14:57:42
Think triggered_auto_reload would be clearer (Make
Elly Fong-Jones
2014/04/25 20:01:26
Done.
| |
| 291 }; | 295 }; |
| 292 | 296 |
| 293 bool NetErrorHelperCore::IsReloadableError( | 297 bool NetErrorHelperCore::IsReloadableError( |
| 294 const NetErrorHelperCore::ErrorPageInfo& info) { | 298 const NetErrorHelperCore::ErrorPageInfo& info) { |
| 295 return info.error.domain.utf8() == net::kErrorDomain && | 299 return info.error.domain.utf8() == net::kErrorDomain && |
| 296 info.error.reason != net::ERR_ABORTED && | 300 info.error.reason != net::ERR_ABORTED && |
| 297 !info.was_failed_post; | 301 !info.was_failed_post; |
| 298 } | 302 } |
| 299 | 303 |
| 300 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) | 304 NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate) |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 315 -committed_error_page_info_->error.reason, | 319 -committed_error_page_info_->error.reason, |
| 316 net::GetAllErrorCodesForUma()); | 320 net::GetAllErrorCodesForUma()); |
| 317 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_); | 321 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_); |
| 318 } | 322 } |
| 319 } | 323 } |
| 320 | 324 |
| 321 void NetErrorHelperCore::CancelPendingFetches() { | 325 void NetErrorHelperCore::CancelPendingFetches() { |
| 322 // Cancel loading the alternate error page, and prevent any pending error page | 326 // Cancel loading the alternate error page, and prevent any pending error page |
| 323 // load from starting a new error page load. Swapping in the error page when | 327 // load from starting a new error page load. Swapping in the error page when |
| 324 // it's finished loading could abort the navigation, otherwise. | 328 // it's finished loading could abort the navigation, otherwise. |
| 325 if (committed_error_page_info_ && can_auto_reload_page_) { | |
| 326 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop", | |
| 327 -committed_error_page_info_->error.reason, | |
| 328 net::GetAllErrorCodesForUma()); | |
| 329 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", auto_reload_count_); | |
| 330 } | |
| 331 if (committed_error_page_info_) { | 329 if (committed_error_page_info_) { |
| 332 committed_error_page_info_->navigation_correction_url = GURL(); | 330 committed_error_page_info_->navigation_correction_url = GURL(); |
| 333 committed_error_page_info_->navigation_correction_request_body.clear(); | 331 committed_error_page_info_->navigation_correction_request_body.clear(); |
| 334 } | 332 } |
| 335 if (pending_error_page_info_) { | 333 if (pending_error_page_info_) { |
| 336 pending_error_page_info_->navigation_correction_url = GURL(); | 334 pending_error_page_info_->navigation_correction_url = GURL(); |
| 337 pending_error_page_info_->navigation_correction_request_body.clear(); | 335 pending_error_page_info_->navigation_correction_request_body.clear(); |
| 338 } | 336 } |
| 339 delegate_->CancelFetchNavigationCorrections(); | 337 delegate_->CancelFetchNavigationCorrections(); |
| 340 auto_reload_timer_->Stop(); | 338 auto_reload_timer_->Stop(); |
| 341 can_auto_reload_page_ = false; | 339 can_auto_reload_page_ = false; |
| 342 } | 340 } |
| 343 | 341 |
| 344 void NetErrorHelperCore::OnStop() { | 342 void NetErrorHelperCore::OnStop() { |
| 343 if (committed_error_page_info_ && | |
| 344 (committed_error_page_info_->is_auto_reloading || | |
| 345 auto_reload_timer_->IsRunning())) { | |
|
mmenke
2014/04/25 14:57:42
So if a user presses stop while the autoreload tim
Elly Fong-Jones
2014/04/25 20:01:26
If they trigger a new navigation while it's runnin
mmenke
2014/04/25 20:08:03
But autoreload won't have been triggered. We reco
| |
| 346 ReportAutoReloadFailure(committed_error_page_info_->error.reason, | |
| 347 auto_reload_count_); | |
| 348 } | |
| 345 CancelPendingFetches(); | 349 CancelPendingFetches(); |
| 346 auto_reload_count_ = 0; | 350 auto_reload_count_ = 0; |
| 347 } | 351 } |
| 348 | 352 |
| 349 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { | 353 void NetErrorHelperCore::OnStartLoad(FrameType frame_type, PageType page_type) { |
| 350 if (frame_type != MAIN_FRAME) | 354 if (frame_type != MAIN_FRAME) |
| 351 return; | 355 return; |
| 352 | 356 |
| 353 // If there's no pending error page information associated with the page load, | 357 // If there's no pending error page information associated with the page load, |
| 354 // or the new page is not an error page, then reset pending error page state. | 358 // or the new page is not an error page, then reset pending error page state. |
| 355 if (!pending_error_page_info_ || page_type != ERROR_PAGE) { | 359 if (!pending_error_page_info_ || page_type != ERROR_PAGE) { |
| 356 CancelPendingFetches(); | 360 CancelPendingFetches(); |
| 357 } else if (auto_reload_enabled_) { | 361 } else if (auto_reload_enabled_) { |
| 358 // If an error load is starting, the resulting error page is autoreloadable. | 362 // If an error load is starting, the resulting error page is autoreloadable. |
| 359 can_auto_reload_page_ = IsReloadableError(*pending_error_page_info_); | 363 can_auto_reload_page_ = IsReloadableError(*pending_error_page_info_); |
| 360 } | 364 } |
| 361 } | 365 } |
| 362 | 366 |
| 363 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type) { | 367 void NetErrorHelperCore::OnCommitLoad(FrameType frame_type, const GURL& url) { |
| 364 if (frame_type != MAIN_FRAME) | 368 if (frame_type != MAIN_FRAME) |
| 365 return; | 369 return; |
| 366 | 370 |
| 367 // Track if an error occurred due to a page button press. | 371 // Track if an error occurred due to a page button press. |
| 368 // This isn't perfect; if (for instance), the server is slow responding | 372 // This isn't perfect; if (for instance), the server is slow responding |
| 369 // to a request generated from the page reload button, and the user hits | 373 // to a request generated from the page reload button, and the user hits |
| 370 // the browser reload button, this code will still believe the | 374 // the browser reload button, this code will still believe the |
| 371 // result is from the page reload button. | 375 // result is from the page reload button. |
| 372 if (committed_error_page_info_ && pending_error_page_info_ && | 376 if (committed_error_page_info_ && pending_error_page_info_ && |
| 373 navigation_from_button_ != NO_BUTTON && | 377 navigation_from_button_ != NO_BUTTON && |
| 374 committed_error_page_info_->error.unreachableURL == | 378 committed_error_page_info_->error.unreachableURL == |
| 375 pending_error_page_info_->error.unreachableURL) { | 379 pending_error_page_info_->error.unreachableURL) { |
| 376 DCHECK(navigation_from_button_ == RELOAD_BUTTON || | 380 DCHECK(navigation_from_button_ == RELOAD_BUTTON || |
| 377 navigation_from_button_ == LOAD_STALE_BUTTON); | 381 navigation_from_button_ == LOAD_STALE_BUTTON); |
| 378 chrome_common_net::RecordEvent( | 382 chrome_common_net::RecordEvent( |
| 379 navigation_from_button_ == RELOAD_BUTTON ? | 383 navigation_from_button_ == RELOAD_BUTTON ? |
| 380 chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR : | 384 chrome_common_net::NETWORK_ERROR_PAGE_RELOAD_BUTTON_ERROR : |
| 381 chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_ERROR); | 385 chrome_common_net::NETWORK_ERROR_PAGE_LOAD_STALE_BUTTON_ERROR); |
| 382 } | 386 } |
| 383 navigation_from_button_ = NO_BUTTON; | 387 navigation_from_button_ = NO_BUTTON; |
| 384 | 388 |
| 385 if (committed_error_page_info_ && !pending_error_page_info_ && | 389 if (committed_error_page_info_ && !pending_error_page_info_ && |
| 386 can_auto_reload_page_) { | 390 committed_error_page_info_->is_auto_reloading) { |
| 391 const GURL& error_url = committed_error_page_info_->error.unreachableURL; | |
| 387 int reason = committed_error_page_info_->error.reason; | 392 int reason = committed_error_page_info_->error.reason; |
| 388 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess", | 393 if (url == error_url) |
| 389 -reason, | 394 ReportAutoReloadSuccess(reason, auto_reload_count_); |
| 390 net::GetAllErrorCodesForUma()); | 395 else |
| 391 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", auto_reload_count_); | 396 ReportAutoReloadFailure(reason, auto_reload_count_); |
| 392 if (auto_reload_count_ == 1) { | |
| 393 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess", | |
| 394 -reason, | |
| 395 net::GetAllErrorCodesForUma()); | |
| 396 } | |
| 397 } | 397 } |
| 398 | 398 |
| 399 committed_error_page_info_.reset(pending_error_page_info_.release()); | 399 committed_error_page_info_.reset(pending_error_page_info_.release()); |
| 400 } | 400 } |
| 401 | 401 |
| 402 void NetErrorHelperCore::ReportAutoReloadSuccess(int error, size_t count) { | |
|
mmenke
2014/04/25 14:57:42
These should either be in a private anonymous name
Elly Fong-Jones
2014/04/25 20:01:26
Done.
| |
| 403 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtSuccess", | |
| 404 -error, | |
| 405 net::GetAllErrorCodesForUma()); | |
| 406 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtSuccess", count); | |
| 407 if (count == 1) { | |
| 408 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtFirstSuccess", | |
| 409 -error, | |
| 410 net::GetAllErrorCodesForUma()); | |
| 411 } | |
| 412 } | |
| 413 | |
| 414 void NetErrorHelperCore::ReportAutoReloadFailure(int error, size_t count) { | |
| 415 UMA_HISTOGRAM_CUSTOM_ENUMERATION("Net.AutoReload.ErrorAtStop", | |
| 416 -error, | |
| 417 net::GetAllErrorCodesForUma()); | |
| 418 UMA_HISTOGRAM_COUNTS("Net.AutoReload.CountAtStop", count); | |
| 419 } | |
| 420 | |
| 402 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { | 421 void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) { |
| 403 if (frame_type != MAIN_FRAME) | 422 if (frame_type != MAIN_FRAME) |
| 404 return; | 423 return; |
| 405 | 424 |
| 406 if (!committed_error_page_info_) { | 425 if (!committed_error_page_info_) { |
| 407 auto_reload_count_ = 0; | 426 auto_reload_count_ = 0; |
| 408 return; | 427 return; |
| 409 } | 428 } |
| 410 | 429 |
| 411 committed_error_page_info_->is_finished_loading = true; | 430 committed_error_page_info_->is_finished_loading = true; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 return false; | 658 return false; |
| 640 | 659 |
| 641 StartAutoReloadTimer(); | 660 StartAutoReloadTimer(); |
| 642 return true; | 661 return true; |
| 643 } | 662 } |
| 644 | 663 |
| 645 void NetErrorHelperCore::StartAutoReloadTimer() { | 664 void NetErrorHelperCore::StartAutoReloadTimer() { |
| 646 DCHECK(committed_error_page_info_); | 665 DCHECK(committed_error_page_info_); |
| 647 DCHECK(can_auto_reload_page_); | 666 DCHECK(can_auto_reload_page_); |
| 648 base::TimeDelta delay = GetAutoReloadTime(auto_reload_count_); | 667 base::TimeDelta delay = GetAutoReloadTime(auto_reload_count_); |
| 649 auto_reload_count_++; | |
| 650 auto_reload_timer_->Stop(); | 668 auto_reload_timer_->Stop(); |
| 651 auto_reload_timer_->Start(FROM_HERE, delay, | 669 auto_reload_timer_->Start(FROM_HERE, delay, |
| 652 base::Bind(&NetErrorHelperCore::Reload, | 670 base::Bind(&NetErrorHelperCore::AutoReloadTimerFired, |
| 653 base::Unretained(this))); | 671 base::Unretained(this))); |
| 654 } | 672 } |
| 655 | 673 |
| 674 void NetErrorHelperCore::AutoReloadTimerFired() { | |
| 675 auto_reload_count_++; | |
| 676 committed_error_page_info_->is_auto_reloading = true; | |
| 677 Reload(); | |
| 678 } | |
| 679 | |
| 656 void NetErrorHelperCore::NetworkStateChanged(bool online) { | 680 void NetErrorHelperCore::NetworkStateChanged(bool online) { |
| 657 online_ = online; | 681 online_ = online; |
| 658 if (auto_reload_timer_->IsRunning()) { | 682 if (auto_reload_timer_->IsRunning()) { |
| 659 DCHECK(committed_error_page_info_); | 683 DCHECK(committed_error_page_info_); |
| 660 // If there's an existing timer running, stop it and reset the retry count. | 684 // If there's an existing timer running, stop it and reset the retry count. |
| 661 auto_reload_timer_->Stop(); | 685 auto_reload_timer_->Stop(); |
| 662 auto_reload_count_ = 0; | 686 auto_reload_count_ = 0; |
| 663 } | 687 } |
| 664 | 688 |
| 665 // If the network state changed to online, maybe start auto-reloading again. | 689 // If the network state changed to online, maybe start auto-reloading again. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 715 // Visual effects on page are handled in Javascript code. | 739 // Visual effects on page are handled in Javascript code. |
| 716 chrome_common_net::RecordEvent( | 740 chrome_common_net::RecordEvent( |
| 717 chrome_common_net::NETWORK_ERROR_PAGE_MORE_BUTTON_CLICKED); | 741 chrome_common_net::NETWORK_ERROR_PAGE_MORE_BUTTON_CLICKED); |
| 718 return; | 742 return; |
| 719 case NO_BUTTON: | 743 case NO_BUTTON: |
| 720 NOTREACHED(); | 744 NOTREACHED(); |
| 721 return; | 745 return; |
| 722 } | 746 } |
| 723 } | 747 } |
| 724 | 748 |
| OLD | NEW |