| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/browser/tab_contents/tab_contents.h" | 5 #include "content/browser/tab_contents/tab_contents.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/command_line.h" |
| 10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 11 #include "base/metrics/stats_counters.h" | 12 #include "base/metrics/stats_counters.h" |
| 12 #include "base/string16.h" | 13 #include "base/string16.h" |
| 13 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 14 #include "base/time.h" | 15 #include "base/time.h" |
| 15 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 16 #include "chrome/browser/blocked_content_container.h" | 17 #include "chrome/browser/blocked_content_container.h" |
| 17 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/browser_shutdown.h" | 19 #include "chrome/browser/browser_shutdown.h" |
| 19 #include "chrome/browser/character_encoding.h" | 20 #include "chrome/browser/character_encoding.h" |
| 20 #include "chrome/browser/content_settings/content_settings_details.h" | 21 #include "chrome/browser/content_settings/content_settings_details.h" |
| 21 #include "chrome/browser/content_settings/host_content_settings_map.h" | 22 #include "chrome/browser/content_settings/host_content_settings_map.h" |
| 22 #include "chrome/browser/debugger/devtools_manager.h" | 23 #include "chrome/browser/debugger/devtools_manager.h" |
| 23 #include "chrome/browser/defaults.h" | 24 #include "chrome/browser/defaults.h" |
| 24 #include "chrome/browser/desktop_notification_handler.h" | 25 #include "chrome/browser/desktop_notification_handler.h" |
| 25 #include "chrome/browser/dom_operation_notification_details.h" | 26 #include "chrome/browser/dom_operation_notification_details.h" |
| 26 #include "chrome/browser/download/download_item_model.h" | 27 #include "chrome/browser/download/download_item_model.h" |
| 27 #include "chrome/browser/download/download_manager.h" | 28 #include "chrome/browser/download/download_manager.h" |
| 28 #include "chrome/browser/download/download_request_limiter.h" | 29 #include "chrome/browser/download/download_request_limiter.h" |
| 29 #include "chrome/browser/extensions/extension_service.h" | |
| 30 #include "chrome/browser/external_protocol_handler.h" | 30 #include "chrome/browser/external_protocol_handler.h" |
| 31 #include "chrome/browser/favicon_service.h" | 31 #include "chrome/browser/favicon_service.h" |
| 32 #include "chrome/browser/google/google_util.h" | 32 #include "chrome/browser/google/google_util.h" |
| 33 #include "chrome/browser/history/history.h" | 33 #include "chrome/browser/history/history.h" |
| 34 #include "chrome/browser/history/history_types.h" | 34 #include "chrome/browser/history/history_types.h" |
| 35 #include "chrome/browser/load_from_memory_cache_details.h" | 35 #include "chrome/browser/load_from_memory_cache_details.h" |
| 36 #include "chrome/browser/load_notification_details.h" | 36 #include "chrome/browser/load_notification_details.h" |
| 37 #include "chrome/browser/metrics/metric_event_duration_details.h" | 37 #include "chrome/browser/metrics/metric_event_duration_details.h" |
| 38 #include "chrome/browser/metrics/user_metrics.h" | 38 #include "chrome/browser/metrics/user_metrics.h" |
| 39 #include "chrome/browser/omnibox_search_hint.h" | 39 #include "chrome/browser/omnibox_search_hint.h" |
| 40 #include "chrome/browser/pdf_unsupported_feature.h" | 40 #include "chrome/browser/pdf_unsupported_feature.h" |
| 41 #include "chrome/browser/platform_util.h" | 41 #include "chrome/browser/platform_util.h" |
| 42 #include "chrome/browser/plugin_observer.h" | 42 #include "chrome/browser/plugin_observer.h" |
| 43 #include "chrome/browser/prefs/pref_service.h" |
| 43 #include "chrome/browser/profiles/profile.h" | 44 #include "chrome/browser/profiles/profile.h" |
| 44 #include "chrome/browser/renderer_host/web_cache_manager.h" | 45 #include "chrome/browser/renderer_host/web_cache_manager.h" |
| 45 #include "chrome/browser/renderer_preferences_util.h" | 46 #include "chrome/browser/renderer_preferences_util.h" |
| 46 #include "chrome/browser/safe_browsing/client_side_detection_host.h" | 47 #include "chrome/browser/safe_browsing/client_side_detection_host.h" |
| 47 #include "chrome/browser/sessions/session_types.h" | 48 #include "chrome/browser/sessions/session_types.h" |
| 48 #include "chrome/browser/tab_contents/infobar_delegate.h" | 49 #include "chrome/browser/tab_contents/infobar_delegate.h" |
| 49 #include "chrome/browser/tab_contents/tab_contents_ssl_helper.h" | 50 #include "chrome/browser/tab_contents/tab_contents_ssl_helper.h" |
| 50 #include "chrome/browser/tab_contents/thumbnail_generator.h" | 51 #include "chrome/browser/tab_contents/thumbnail_generator.h" |
| 51 #include "chrome/browser/translate/page_translated_details.h" | 52 #include "chrome/browser/translate/page_translated_details.h" |
| 52 #include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" | 53 #include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" |
| 53 #include "chrome/browser/ui/browser_dialogs.h" | 54 #include "chrome/browser/ui/browser_dialogs.h" |
| 54 #include "chrome/common/bindings_policy.h" | 55 #include "chrome/common/bindings_policy.h" |
| 55 #include "chrome/common/chrome_constants.h" | 56 #include "chrome/common/chrome_constants.h" |
| 56 #include "chrome/common/chrome_switches.h" | 57 #include "chrome/common/chrome_switches.h" |
| 57 #include "chrome/common/content_restriction.h" | 58 #include "chrome/common/content_restriction.h" |
| 58 #include "chrome/common/extensions/extension.h" | 59 #include "chrome/common/extensions/extension.h" |
| 59 #include "chrome/common/extensions/extension_action.h" | |
| 60 #include "chrome/common/extensions/extension_icon_set.h" | |
| 61 #include "chrome/common/extensions/extension_messages.h" | 60 #include "chrome/common/extensions/extension_messages.h" |
| 62 #include "chrome/common/extensions/extension_resource.h" | |
| 63 #include "chrome/common/extensions/url_pattern.h" | 61 #include "chrome/common/extensions/url_pattern.h" |
| 64 #include "chrome/common/pref_names.h" | 62 #include "chrome/common/pref_names.h" |
| 65 #include "chrome/common/render_messages.h" | 63 #include "chrome/common/render_messages.h" |
| 66 #include "chrome/common/url_constants.h" | 64 #include "chrome/common/url_constants.h" |
| 67 #include "content/browser/child_process_security_policy.h" | 65 #include "content/browser/child_process_security_policy.h" |
| 68 #include "content/browser/content_browser_client.h" | 66 #include "content/browser/content_browser_client.h" |
| 69 #include "content/browser/host_zoom_map.h" | 67 #include "content/browser/host_zoom_map.h" |
| 70 #include "content/browser/in_process_webkit/session_storage_namespace.h" | 68 #include "content/browser/in_process_webkit/session_storage_namespace.h" |
| 71 #include "content/browser/renderer_host/render_process_host.h" | 69 #include "content/browser/renderer_host/render_process_host.h" |
| 72 #include "content/browser/renderer_host/render_view_host.h" | 70 #include "content/browser/renderer_host/render_view_host.h" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 waiting_for_response_(false), | 234 waiting_for_response_(false), |
| 237 max_page_id_(-1), | 235 max_page_id_(-1), |
| 238 load_state_(net::LOAD_STATE_IDLE), | 236 load_state_(net::LOAD_STATE_IDLE), |
| 239 upload_size_(0), | 237 upload_size_(0), |
| 240 upload_position_(0), | 238 upload_position_(0), |
| 241 received_page_title_(false), | 239 received_page_title_(false), |
| 242 blocked_contents_(NULL), | 240 blocked_contents_(NULL), |
| 243 all_contents_blocked_(false), | 241 all_contents_blocked_(false), |
| 244 dont_notify_render_view_(false), | 242 dont_notify_render_view_(false), |
| 245 displayed_insecure_content_(false), | 243 displayed_insecure_content_(false), |
| 246 extension_app_(NULL), | |
| 247 capturing_contents_(false), | 244 capturing_contents_(false), |
| 248 is_being_destroyed_(false), | 245 is_being_destroyed_(false), |
| 249 notify_disconnection_(false), | 246 notify_disconnection_(false), |
| 250 #if defined(OS_WIN) | 247 #if defined(OS_WIN) |
| 251 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), | 248 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), |
| 252 #endif | 249 #endif |
| 253 suppress_javascript_messages_(false), | 250 suppress_javascript_messages_(false), |
| 254 is_showing_before_unload_dialog_(false), | 251 is_showing_before_unload_dialog_(false), |
| 255 opener_web_ui_type_(WebUI::kNoWebUI), | 252 opener_web_ui_type_(WebUI::kNoWebUI), |
| 256 language_state_(&controller_), | 253 language_state_(&controller_), |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 TabContentsSSLHelper* TabContents::GetSSLHelper() { | 441 TabContentsSSLHelper* TabContents::GetSSLHelper() { |
| 445 if (ssl_helper_.get() == NULL) | 442 if (ssl_helper_.get() == NULL) |
| 446 ssl_helper_.reset(new TabContentsSSLHelper(this)); | 443 ssl_helper_.reset(new TabContentsSSLHelper(this)); |
| 447 return ssl_helper_.get(); | 444 return ssl_helper_.get(); |
| 448 } | 445 } |
| 449 | 446 |
| 450 RenderProcessHost* TabContents::GetRenderProcessHost() const { | 447 RenderProcessHost* TabContents::GetRenderProcessHost() const { |
| 451 return render_manager_.current_host()->process(); | 448 return render_manager_.current_host()->process(); |
| 452 } | 449 } |
| 453 | 450 |
| 454 void TabContents::SetExtensionApp(const Extension* extension) { | |
| 455 DCHECK(!extension || extension->GetFullLaunchURL().is_valid()); | |
| 456 extension_app_ = extension; | |
| 457 | |
| 458 UpdateExtensionAppIcon(extension_app_); | |
| 459 | |
| 460 NotificationService::current()->Notify( | |
| 461 NotificationType::TAB_CONTENTS_APPLICATION_EXTENSION_CHANGED, | |
| 462 Source<TabContents>(this), | |
| 463 NotificationService::NoDetails()); | |
| 464 } | |
| 465 | |
| 466 void TabContents::SetExtensionAppById(const std::string& extension_app_id) { | |
| 467 if (extension_app_id.empty()) | |
| 468 return; | |
| 469 | |
| 470 ExtensionService* extension_service = profile()->GetExtensionService(); | |
| 471 if (!extension_service || !extension_service->is_ready()) | |
| 472 return; | |
| 473 | |
| 474 const Extension* extension = | |
| 475 extension_service->GetExtensionById(extension_app_id, false); | |
| 476 if (extension) | |
| 477 SetExtensionApp(extension); | |
| 478 } | |
| 479 | |
| 480 SkBitmap* TabContents::GetExtensionAppIcon() { | |
| 481 if (extension_app_icon_.empty()) | |
| 482 return NULL; | |
| 483 | |
| 484 return &extension_app_icon_; | |
| 485 } | |
| 486 | |
| 487 const GURL& TabContents::GetURL() const { | 451 const GURL& TabContents::GetURL() const { |
| 488 // We may not have a navigation entry yet | 452 // We may not have a navigation entry yet |
| 489 NavigationEntry* entry = controller_.GetActiveEntry(); | 453 NavigationEntry* entry = controller_.GetActiveEntry(); |
| 490 return entry ? entry->virtual_url() : GURL::EmptyGURL(); | 454 return entry ? entry->virtual_url() : GURL::EmptyGURL(); |
| 491 } | 455 } |
| 492 | 456 |
| 493 const string16& TabContents::GetTitle() const { | 457 const string16& TabContents::GetTitle() const { |
| 494 // Transient entries take precedence. They are used for interstitial pages | 458 // Transient entries take precedence. They are used for interstitial pages |
| 495 // that are shown on top of existing pages. | 459 // that are shown on top of existing pages. |
| 496 NavigationEntry* entry = controller_.GetTransientEntry(); | 460 NavigationEntry* entry = controller_.GetTransientEntry(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 | 571 |
| 608 void TabContents::SetIsCrashed(base::TerminationStatus status, int error_code) { | 572 void TabContents::SetIsCrashed(base::TerminationStatus status, int error_code) { |
| 609 if (status == crashed_status_) | 573 if (status == crashed_status_) |
| 610 return; | 574 return; |
| 611 | 575 |
| 612 crashed_status_ = status; | 576 crashed_status_ = status; |
| 613 crashed_error_code_ = error_code; | 577 crashed_error_code_ = error_code; |
| 614 NotifyNavigationStateChanged(INVALIDATE_TAB); | 578 NotifyNavigationStateChanged(INVALIDATE_TAB); |
| 615 } | 579 } |
| 616 | 580 |
| 617 void TabContents::PageActionStateChanged() { | |
| 618 NotifyNavigationStateChanged(TabContents::INVALIDATE_PAGE_ACTIONS); | |
| 619 } | |
| 620 | |
| 621 void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) { | 581 void TabContents::NotifyNavigationStateChanged(unsigned changed_flags) { |
| 622 if (delegate_) | 582 if (delegate_) |
| 623 delegate_->NavigationStateChanged(this, changed_flags); | 583 delegate_->NavigationStateChanged(this, changed_flags); |
| 624 } | 584 } |
| 625 | 585 |
| 626 void TabContents::DidBecomeSelected() { | 586 void TabContents::DidBecomeSelected() { |
| 627 controller_.SetActive(true); | 587 controller_.SetActive(true); |
| 628 RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); | 588 RenderWidgetHostView* rwhv = GetRenderWidgetHostView(); |
| 629 if (rwhv) { | 589 if (rwhv) { |
| 630 rwhv->DidBecomeSelected(); | 590 rwhv->DidBecomeSelected(); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 } | 735 } |
| 776 | 736 |
| 777 TabContents* TabContents::Clone() { | 737 TabContents* TabContents::Clone() { |
| 778 // We create a new SiteInstance so that the new tab won't share processes | 738 // We create a new SiteInstance so that the new tab won't share processes |
| 779 // with the old one. This can be changed in the future if we need it to share | 739 // with the old one. This can be changed in the future if we need it to share |
| 780 // processes for some reason. | 740 // processes for some reason. |
| 781 TabContents* tc = new TabContents(profile(), | 741 TabContents* tc = new TabContents(profile(), |
| 782 SiteInstance::CreateSiteInstance(profile()), | 742 SiteInstance::CreateSiteInstance(profile()), |
| 783 MSG_ROUTING_NONE, this, NULL); | 743 MSG_ROUTING_NONE, this, NULL); |
| 784 tc->controller().CopyStateFrom(controller_); | 744 tc->controller().CopyStateFrom(controller_); |
| 785 tc->extension_app_ = extension_app_; | |
| 786 tc->extension_app_icon_ = extension_app_icon_; | |
| 787 return tc; | 745 return tc; |
| 788 } | 746 } |
| 789 | 747 |
| 790 void TabContents::ShowPageInfo(const GURL& url, | 748 void TabContents::ShowPageInfo(const GURL& url, |
| 791 const NavigationEntry::SSLStatus& ssl, | 749 const NavigationEntry::SSLStatus& ssl, |
| 792 bool show_history) { | 750 bool show_history) { |
| 793 if (!delegate_) | 751 if (!delegate_) |
| 794 return; | 752 return; |
| 795 | 753 |
| 796 delegate_->ShowPageInfo(profile(), url, ssl, show_history); | 754 delegate_->ShowPageInfo(profile(), url, ssl, show_history); |
| (...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1632 | 1590 |
| 1633 // Allow the new page to set the title again. | 1591 // Allow the new page to set the title again. |
| 1634 received_page_title_ = false; | 1592 received_page_title_ = false; |
| 1635 | 1593 |
| 1636 // Get the favicon, either from history or request it from the net. | 1594 // Get the favicon, either from history or request it from the net. |
| 1637 favicon_helper_->FetchFavicon(details.entry->url()); | 1595 favicon_helper_->FetchFavicon(details.entry->url()); |
| 1638 | 1596 |
| 1639 // Clear all page actions, blocked content notifications and browser actions | 1597 // Clear all page actions, blocked content notifications and browser actions |
| 1640 // for this tab, unless this is an in-page navigation. | 1598 // for this tab, unless this is an in-page navigation. |
| 1641 if (!details.is_in_page) { | 1599 if (!details.is_in_page) { |
| 1642 ExtensionService* service = profile()->GetExtensionService(); | |
| 1643 if (service) { | |
| 1644 for (size_t i = 0; i < service->extensions()->size(); ++i) { | |
| 1645 ExtensionAction* browser_action = | |
| 1646 service->extensions()->at(i)->browser_action(); | |
| 1647 if (browser_action) { | |
| 1648 browser_action->ClearAllValuesForTab(controller().session_id().id()); | |
| 1649 NotificationService::current()->Notify( | |
| 1650 NotificationType::EXTENSION_BROWSER_ACTION_UPDATED, | |
| 1651 Source<ExtensionAction>(browser_action), | |
| 1652 NotificationService::NoDetails()); | |
| 1653 } | |
| 1654 | |
| 1655 ExtensionAction* page_action = | |
| 1656 service->extensions()->at(i)->page_action(); | |
| 1657 if (page_action) { | |
| 1658 page_action->ClearAllValuesForTab(controller().session_id().id()); | |
| 1659 PageActionStateChanged(); | |
| 1660 } | |
| 1661 } | |
| 1662 } | |
| 1663 | |
| 1664 // Close blocked popups. | 1600 // Close blocked popups. |
| 1665 if (blocked_contents_) { | 1601 if (blocked_contents_) { |
| 1666 AutoReset<bool> auto_reset(&dont_notify_render_view_, true); | 1602 AutoReset<bool> auto_reset(&dont_notify_render_view_, true); |
| 1667 blocked_contents_->Destroy(); | 1603 blocked_contents_->Destroy(); |
| 1668 blocked_contents_ = NULL; | 1604 blocked_contents_ = NULL; |
| 1669 } | 1605 } |
| 1670 | 1606 |
| 1671 // Clear "blocked" flags. | 1607 // Clear "blocked" flags. |
| 1672 content_settings_delegate_->ClearBlockedContentSettingsExceptForCookies(); | 1608 content_settings_delegate_->ClearBlockedContentSettingsExceptForCookies(); |
| 1673 content_settings_delegate_->GeolocationDidNavigate(details); | 1609 content_settings_delegate_->GeolocationDidNavigate(details); |
| (...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2660 | 2596 |
| 2661 case NotificationType::GOOGLE_URL_UPDATED: | 2597 case NotificationType::GOOGLE_URL_UPDATED: |
| 2662 UpdateAlternateErrorPageURL(); | 2598 UpdateAlternateErrorPageURL(); |
| 2663 break; | 2599 break; |
| 2664 | 2600 |
| 2665 default: | 2601 default: |
| 2666 NOTREACHED(); | 2602 NOTREACHED(); |
| 2667 } | 2603 } |
| 2668 } | 2604 } |
| 2669 | 2605 |
| 2670 void TabContents::UpdateExtensionAppIcon(const Extension* extension) { | |
| 2671 extension_app_icon_.reset(); | |
| 2672 | |
| 2673 if (extension) { | |
| 2674 extension_app_image_loader_.reset(new ImageLoadingTracker(this)); | |
| 2675 extension_app_image_loader_->LoadImage( | |
| 2676 extension, | |
| 2677 extension->GetIconResource(Extension::EXTENSION_ICON_SMALLISH, | |
| 2678 ExtensionIconSet::MATCH_EXACTLY), | |
| 2679 gfx::Size(Extension::EXTENSION_ICON_SMALLISH, | |
| 2680 Extension::EXTENSION_ICON_SMALLISH), | |
| 2681 ImageLoadingTracker::CACHE); | |
| 2682 } else { | |
| 2683 extension_app_image_loader_.reset(NULL); | |
| 2684 } | |
| 2685 } | |
| 2686 | |
| 2687 const Extension* TabContents::GetExtensionContaining(const GURL& url) { | |
| 2688 ExtensionService* extensions_service = profile()->GetExtensionService(); | |
| 2689 if (!extensions_service) | |
| 2690 return NULL; | |
| 2691 | |
| 2692 const Extension* extension = extensions_service->GetExtensionByURL(url); | |
| 2693 return extension ? | |
| 2694 extension : extensions_service->GetExtensionByWebExtent(url); | |
| 2695 } | |
| 2696 | |
| 2697 void TabContents::OnImageLoaded(SkBitmap* image, | |
| 2698 const ExtensionResource& resource, | |
| 2699 int index) { | |
| 2700 if (image) { | |
| 2701 extension_app_icon_ = *image; | |
| 2702 NotifyNavigationStateChanged(INVALIDATE_TAB); | |
| 2703 } | |
| 2704 } | |
| 2705 | |
| 2706 gfx::NativeWindow TabContents::GetMessageBoxRootWindow() { | 2606 gfx::NativeWindow TabContents::GetMessageBoxRootWindow() { |
| 2707 return view_->GetTopLevelNativeWindow(); | 2607 return view_->GetTopLevelNativeWindow(); |
| 2708 } | 2608 } |
| 2709 | 2609 |
| 2710 void TabContents::OnMessageBoxClosed(IPC::Message* reply_msg, | 2610 void TabContents::OnMessageBoxClosed(IPC::Message* reply_msg, |
| 2711 bool success, | 2611 bool success, |
| 2712 const std::wstring& prompt) { | 2612 const std::wstring& prompt) { |
| 2713 last_javascript_message_dismissal_ = base::TimeTicks::Now(); | 2613 last_javascript_message_dismissal_ = base::TimeTicks::Now(); |
| 2714 if (is_showing_before_unload_dialog_ && !success) { | 2614 if (is_showing_before_unload_dialog_ && !success) { |
| 2715 // If a beforeunload dialog is canceled, we need to stop the throbber from | 2615 // If a beforeunload dialog is canceled, we need to stop the throbber from |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 | 2649 |
| 2750 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { | 2650 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { |
| 2751 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); | 2651 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); |
| 2752 rwh_view->SetSize(view()->GetContainerSize()); | 2652 rwh_view->SetSize(view()->GetContainerSize()); |
| 2753 } | 2653 } |
| 2754 | 2654 |
| 2755 void TabContents::OnOnlineStateChanged(bool online) { | 2655 void TabContents::OnOnlineStateChanged(bool online) { |
| 2756 render_view_host()->Send(new ViewMsg_NetworkStateChanged( | 2656 render_view_host()->Send(new ViewMsg_NetworkStateChanged( |
| 2757 render_view_host()->routing_id(), online)); | 2657 render_view_host()->routing_id(), online)); |
| 2758 } | 2658 } |
| OLD | NEW |