| 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" | |
| 10 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 11 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 12 #include "base/metrics/stats_counters.h" | 11 #include "base/metrics/stats_counters.h" |
| 13 #include "base/string16.h" | 12 #include "base/string16.h" |
| 14 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 15 #include "base/time.h" | 14 #include "base/time.h" |
| 16 #include "base/utf_string_conversions.h" | 15 #include "base/utf_string_conversions.h" |
| 17 #include "chrome/browser/blocked_content_container.h" | |
| 18 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 19 #include "chrome/browser/browser_shutdown.h" | 17 #include "chrome/browser/browser_shutdown.h" |
| 20 #include "chrome/browser/character_encoding.h" | 18 #include "chrome/browser/character_encoding.h" |
| 21 #include "chrome/browser/content_settings/content_settings_details.h" | 19 #include "chrome/browser/content_settings/content_settings_details.h" |
| 22 #include "chrome/browser/content_settings/host_content_settings_map.h" | 20 #include "chrome/browser/content_settings/host_content_settings_map.h" |
| 23 #include "chrome/browser/debugger/devtools_manager.h" | 21 #include "chrome/browser/debugger/devtools_manager.h" |
| 24 #include "chrome/browser/defaults.h" | 22 #include "chrome/browser/defaults.h" |
| 25 #include "chrome/browser/dom_operation_notification_details.h" | 23 #include "chrome/browser/dom_operation_notification_details.h" |
| 26 #include "chrome/browser/download/download_item_model.h" | 24 #include "chrome/browser/download/download_item_model.h" |
| 27 #include "chrome/browser/download/download_manager.h" | 25 #include "chrome/browser/download/download_manager.h" |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 bookmark_drag_(NULL), | 230 bookmark_drag_(NULL), |
| 233 is_loading_(false), | 231 is_loading_(false), |
| 234 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), | 232 crashed_status_(base::TERMINATION_STATUS_STILL_RUNNING), |
| 235 crashed_error_code_(0), | 233 crashed_error_code_(0), |
| 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), | |
| 243 all_contents_blocked_(false), | |
| 244 displayed_insecure_content_(false), | 240 displayed_insecure_content_(false), |
| 245 capturing_contents_(false), | 241 capturing_contents_(false), |
| 246 is_being_destroyed_(false), | 242 is_being_destroyed_(false), |
| 247 notify_disconnection_(false), | 243 notify_disconnection_(false), |
| 248 #if defined(OS_WIN) | 244 #if defined(OS_WIN) |
| 249 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), | 245 message_box_active_(CreateEvent(NULL, TRUE, FALSE, NULL)), |
| 250 #endif | 246 #endif |
| 251 suppress_javascript_messages_(false), | 247 suppress_javascript_messages_(false), |
| 252 is_showing_before_unload_dialog_(false), | 248 is_showing_before_unload_dialog_(false), |
| 253 opener_web_ui_type_(WebUI::kNoWebUI), | 249 opener_web_ui_type_(WebUI::kNoWebUI), |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 320 |
| 325 NotifyDisconnected(); | 321 NotifyDisconnected(); |
| 326 browser::HideHungRendererDialog(this); | 322 browser::HideHungRendererDialog(this); |
| 327 | 323 |
| 328 // First cleanly close all child windows. | 324 // First cleanly close all child windows. |
| 329 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked | 325 // TODO(mpcomplete): handle case if MaybeCloseChildWindows() already asked |
| 330 // some of these to close. CloseWindows is async, so it might get called | 326 // some of these to close. CloseWindows is async, so it might get called |
| 331 // twice before it runs. | 327 // twice before it runs. |
| 332 CloseConstrainedWindows(); | 328 CloseConstrainedWindows(); |
| 333 | 329 |
| 334 // Close all blocked contents. | |
| 335 if (blocked_contents_) | |
| 336 blocked_contents_->Destroy(); | |
| 337 | |
| 338 // Notify any observer that have a reference on this tab contents. | 330 // Notify any observer that have a reference on this tab contents. |
| 339 NotificationService::current()->Notify( | 331 NotificationService::current()->Notify( |
| 340 NotificationType::TAB_CONTENTS_DESTROYED, | 332 NotificationType::TAB_CONTENTS_DESTROYED, |
| 341 Source<TabContents>(this), | 333 Source<TabContents>(this), |
| 342 NotificationService::NoDetails()); | 334 NotificationService::NoDetails()); |
| 343 | 335 |
| 344 // Notify any lasting InfobarDelegates that have not yet been removed that | 336 // Notify any lasting InfobarDelegates that have not yet been removed that |
| 345 // whatever infobar they were handling in this TabContents has closed, | 337 // whatever infobar they were handling in this TabContents has closed, |
| 346 // because the TabContents is going away entirely. | 338 // because the TabContents is going away entirely. |
| 347 // This must happen after the TAB_CONTENTS_DESTROYED notification as the | 339 // This must happen after the TAB_CONTENTS_DESTROYED notification as the |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 SkColor greyish = SkColorSetARGB(178, 0, 0, 0); | 796 SkColor greyish = SkColorSetARGB(178, 0, 0, 0); |
| 805 if (rwhv) | 797 if (rwhv) |
| 806 rwhv->SetVisuallyDeemphasized(blocked ? &greyish : NULL, false); | 798 rwhv->SetVisuallyDeemphasized(blocked ? &greyish : NULL, false); |
| 807 // RenderViewHost may be NULL during shutdown. | 799 // RenderViewHost may be NULL during shutdown. |
| 808 if (render_view_host()) | 800 if (render_view_host()) |
| 809 render_view_host()->set_ignore_input_events(blocked); | 801 render_view_host()->set_ignore_input_events(blocked); |
| 810 if (delegate_) | 802 if (delegate_) |
| 811 delegate_->SetTabContentBlocked(this, blocked); | 803 delegate_->SetTabContentBlocked(this, blocked); |
| 812 } | 804 } |
| 813 | 805 |
| 814 | 806 void TabContents::AddNewContents(TabContents* new_contents, |
| 815 void TabContents::AddOrBlockNewContents(TabContents* new_contents, | 807 WindowOpenDisposition disposition, |
| 816 WindowOpenDisposition disposition, | 808 const gfx::Rect& initial_pos, |
| 817 const gfx::Rect& initial_pos, | 809 bool user_gesture) { |
| 818 bool user_gesture) { | |
| 819 if (all_contents_blocked_) { | |
| 820 if (!blocked_contents_) | |
| 821 blocked_contents_ = new BlockedContentContainer(this); | |
| 822 blocked_contents_->AddTabContents( | |
| 823 new_contents, disposition, initial_pos, user_gesture); | |
| 824 return; | |
| 825 } | |
| 826 | |
| 827 if (!delegate_) | 810 if (!delegate_) |
| 828 return; | 811 return; |
| 829 | 812 |
| 830 if ((disposition == NEW_POPUP) && !user_gesture && | 813 delegate_->AddNewContents(this, new_contents, disposition, initial_pos, |
| 831 !CommandLine::ForCurrentProcess()->HasSwitch( | 814 user_gesture); |
| 832 switches::kDisablePopupBlocking)) { | |
| 833 // Unrequested popups from normal pages are constrained unless they're in | |
| 834 // the whitelist. The popup owner will handle checking this. | |
| 835 delegate_->GetConstrainingContents(this)->AddPopup( | |
| 836 new_contents, initial_pos, user_gesture); | |
| 837 } else { | |
| 838 AddNewContents(new_contents, disposition, initial_pos, user_gesture); | |
| 839 } | |
| 840 | |
| 841 // TODO(pkasting): Why is this necessary? | |
| 842 PopupNotificationVisibilityChanged(blocked_contents_ != NULL); | |
| 843 } | |
| 844 | |
| 845 void TabContents::PopupNotificationVisibilityChanged(bool visible) { | |
| 846 if (is_being_destroyed_) | |
| 847 return; | |
| 848 content_settings_delegate_->SetPopupsBlocked(visible); | |
| 849 } | 815 } |
| 850 | 816 |
| 851 gfx::NativeView TabContents::GetContentNativeView() const { | 817 gfx::NativeView TabContents::GetContentNativeView() const { |
| 852 return view_->GetContentNativeView(); | 818 return view_->GetContentNativeView(); |
| 853 } | 819 } |
| 854 | 820 |
| 855 gfx::NativeView TabContents::GetNativeView() const { | 821 gfx::NativeView TabContents::GetNativeView() const { |
| 856 return view_->GetNativeView(); | 822 return view_->GetNativeView(); |
| 857 } | 823 } |
| 858 | 824 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 child_windows_.erase(i); | 990 child_windows_.erase(i); |
| 1025 if (child_windows_.empty()) { | 991 if (child_windows_.empty()) { |
| 1026 BlockTabContent(false); | 992 BlockTabContent(false); |
| 1027 } else { | 993 } else { |
| 1028 if (removed_topmost_window) | 994 if (removed_topmost_window) |
| 1029 child_windows_[0]->ShowConstrainedWindow(); | 995 child_windows_[0]->ShowConstrainedWindow(); |
| 1030 BlockTabContent(true); | 996 BlockTabContent(true); |
| 1031 } | 997 } |
| 1032 } | 998 } |
| 1033 | 999 |
| 1034 void TabContents::WillCloseBlockedContentContainer( | |
| 1035 BlockedContentContainer* container) { | |
| 1036 DCHECK(blocked_contents_ == container); | |
| 1037 blocked_contents_ = NULL; | |
| 1038 PopupNotificationVisibilityChanged(false); | |
| 1039 } | |
| 1040 | |
| 1041 void TabContents::EmailPageLocation() { | 1000 void TabContents::EmailPageLocation() { |
| 1042 std::string title = EscapeQueryParamValue(UTF16ToUTF8(GetTitle()), false); | 1001 std::string title = EscapeQueryParamValue(UTF16ToUTF8(GetTitle()), false); |
| 1043 std::string page_url = EscapeQueryParamValue(GetURL().spec(), false); | 1002 std::string page_url = EscapeQueryParamValue(GetURL().spec(), false); |
| 1044 std::string mailto = std::string("mailto:?subject=Fwd:%20") + | 1003 std::string mailto = std::string("mailto:?subject=Fwd:%20") + |
| 1045 title + "&body=%0A%0A" + page_url; | 1004 title + "&body=%0A%0A" + page_url; |
| 1046 platform_util::OpenExternal(GURL(mailto)); | 1005 platform_util::OpenExternal(GURL(mailto)); |
| 1047 } | 1006 } |
| 1048 | 1007 |
| 1049 bool TabContents::IsActiveEntry(int32 page_id) { | 1008 bool TabContents::IsActiveEntry(int32 page_id) { |
| 1050 NavigationEntry* active_entry = controller_.GetActiveEntry(); | 1009 NavigationEntry* active_entry = controller_.GetActiveEntry(); |
| 1051 return (active_entry != NULL && | 1010 return (active_entry != NULL && |
| 1052 active_entry->site_instance() == GetSiteInstance() && | 1011 active_entry->site_instance() == GetSiteInstance() && |
| 1053 active_entry->page_id() == page_id); | 1012 active_entry->page_id() == page_id); |
| 1054 } | 1013 } |
| 1055 | 1014 |
| 1056 void TabContents::SetOverrideEncoding(const std::string& encoding) { | 1015 void TabContents::SetOverrideEncoding(const std::string& encoding) { |
| 1057 set_encoding(encoding); | 1016 set_encoding(encoding); |
| 1058 render_view_host()->SetPageEncoding(encoding); | 1017 render_view_host()->SetPageEncoding(encoding); |
| 1059 } | 1018 } |
| 1060 | 1019 |
| 1061 void TabContents::ResetOverrideEncoding() { | 1020 void TabContents::ResetOverrideEncoding() { |
| 1062 reset_encoding(); | 1021 reset_encoding(); |
| 1063 render_view_host()->ResetPageEncodingToDefault(); | 1022 render_view_host()->ResetPageEncodingToDefault(); |
| 1064 } | 1023 } |
| 1065 | 1024 |
| 1066 void TabContents::WindowMoveOrResizeStarted() { | 1025 void TabContents::WindowMoveOrResizeStarted() { |
| 1067 render_view_host()->WindowMoveOrResizeStarted(); | 1026 render_view_host()->WindowMoveOrResizeStarted(); |
| 1068 } | 1027 } |
| 1069 | 1028 |
| 1070 void TabContents::SetAllContentsBlocked(bool value) { | |
| 1071 if (all_contents_blocked_ == value) | |
| 1072 return; | |
| 1073 | |
| 1074 all_contents_blocked_ = value; | |
| 1075 if (!all_contents_blocked_ && blocked_contents_) { | |
| 1076 std::vector<TabContents*> blocked; | |
| 1077 blocked_contents_->GetBlockedContents(&blocked); | |
| 1078 for (size_t i = 0; i < blocked.size(); ++i) | |
| 1079 blocked_contents_->LaunchForContents(blocked[i]); | |
| 1080 } | |
| 1081 } | |
| 1082 | |
| 1083 void TabContents::LogNewTabTime(const std::string& event_name) { | 1029 void TabContents::LogNewTabTime(const std::string& event_name) { |
| 1084 // Not all new tab pages get timed. In those cases, we don't have a | 1030 // Not all new tab pages get timed. In those cases, we don't have a |
| 1085 // new_tab_start_time_. | 1031 // new_tab_start_time_. |
| 1086 if (new_tab_start_time_.is_null()) | 1032 if (new_tab_start_time_.is_null()) |
| 1087 return; | 1033 return; |
| 1088 | 1034 |
| 1089 base::TimeDelta duration = base::TimeTicks::Now() - new_tab_start_time_; | 1035 base::TimeDelta duration = base::TimeTicks::Now() - new_tab_start_time_; |
| 1090 MetricEventDurationDetails details(event_name, | 1036 MetricEventDurationDetails details(event_name, |
| 1091 static_cast<int>(duration.InMilliseconds())); | 1037 static_cast<int>(duration.InMilliseconds())); |
| 1092 | 1038 |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 NotificationType type = is_loading ? NotificationType::LOAD_START : | 1339 NotificationType type = is_loading ? NotificationType::LOAD_START : |
| 1394 NotificationType::LOAD_STOP; | 1340 NotificationType::LOAD_STOP; |
| 1395 NotificationDetails det = NotificationService::NoDetails(); | 1341 NotificationDetails det = NotificationService::NoDetails(); |
| 1396 if (details) | 1342 if (details) |
| 1397 det = Details<LoadNotificationDetails>(details); | 1343 det = Details<LoadNotificationDetails>(details); |
| 1398 NotificationService::current()->Notify(type, | 1344 NotificationService::current()->Notify(type, |
| 1399 Source<NavigationController>(&controller_), | 1345 Source<NavigationController>(&controller_), |
| 1400 det); | 1346 det); |
| 1401 } | 1347 } |
| 1402 | 1348 |
| 1403 void TabContents::AddNewContents(TabContents* new_contents, | |
| 1404 WindowOpenDisposition disposition, | |
| 1405 const gfx::Rect& initial_pos, | |
| 1406 bool user_gesture) { | |
| 1407 new_contents->DisassociateFromPopupCount(); | |
| 1408 delegate_->AddNewContents(this, new_contents, disposition, initial_pos, | |
| 1409 user_gesture); | |
| 1410 NotificationService::current()->Notify( | |
| 1411 NotificationType::TAB_ADDED, | |
| 1412 Source<TabContentsDelegate>(delegate_), | |
| 1413 Details<TabContents>(this)); | |
| 1414 } | |
| 1415 | |
| 1416 void TabContents::AddPopup(TabContents* new_contents, | |
| 1417 const gfx::Rect& initial_pos, | |
| 1418 bool user_gesture) { | |
| 1419 // A page can't spawn popups (or do anything else, either) until its load | |
| 1420 // commits, so when we reach here, the popup was spawned by the | |
| 1421 // NavigationController's last committed entry, not the active entry. For | |
| 1422 // example, if a page opens a popup in an onunload() handler, then the active | |
| 1423 // entry is the page to be loaded as we navigate away from the unloading | |
| 1424 // page. For this reason, we can't use GetURL() to get the opener URL, | |
| 1425 // because it returns the active entry. | |
| 1426 NavigationEntry* entry = controller_.GetLastCommittedEntry(); | |
| 1427 GURL creator = entry ? entry->virtual_url() : GURL::EmptyGURL(); | |
| 1428 | |
| 1429 if (creator.is_valid() && | |
| 1430 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 1431 creator, CONTENT_SETTINGS_TYPE_POPUPS, "") == CONTENT_SETTING_ALLOW) { | |
| 1432 AddNewContents(new_contents, NEW_POPUP, initial_pos, user_gesture); | |
| 1433 } else { | |
| 1434 if (!blocked_contents_) | |
| 1435 blocked_contents_ = new BlockedContentContainer(this); | |
| 1436 // Call blocked_contents_->AddTabContents with user_gesture == true | |
| 1437 // so that the contents will not get blocked again. | |
| 1438 // TODO(stevenjb): Remove user_gesture parameter from | |
| 1439 // BlockedContentContainer::AddTabContents()? | |
| 1440 blocked_contents_->AddTabContents(new_contents, | |
| 1441 NEW_POPUP, | |
| 1442 initial_pos, | |
| 1443 true); // user gesture | |
| 1444 content_settings_delegate_->OnContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS, | |
| 1445 std::string()); | |
| 1446 } | |
| 1447 } | |
| 1448 | |
| 1449 void TabContents::ExpireInfoBars( | 1349 void TabContents::ExpireInfoBars( |
| 1450 const NavigationController::LoadCommittedDetails& details) { | 1350 const NavigationController::LoadCommittedDetails& details) { |
| 1451 // Only hide InfoBars when the user has done something that makes the main | 1351 // Only hide InfoBars when the user has done something that makes the main |
| 1452 // frame load. We don't want various automatic or subframe navigations making | 1352 // frame load. We don't want various automatic or subframe navigations making |
| 1453 // it disappear. | 1353 // it disappear. |
| 1454 if (!details.is_user_initiated_main_frame_load()) | 1354 if (!details.is_user_initiated_main_frame_load()) |
| 1455 return; | 1355 return; |
| 1456 | 1356 |
| 1457 // NOTE: It is not safe to change the following code to count upwards or use | 1357 // NOTE: It is not safe to change the following code to count upwards or use |
| 1458 // iterators, as the RemoveInfoBar() call synchronously modifies our delegate | 1358 // iterators, as the RemoveInfoBar() call synchronously modifies our delegate |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1542 | 1442 |
| 1543 // Get the favicon, either from history or request it from the net. | 1443 // Get the favicon, either from history or request it from the net. |
| 1544 favicon_helper_->FetchFavicon(details.entry->url()); | 1444 favicon_helper_->FetchFavicon(details.entry->url()); |
| 1545 | 1445 |
| 1546 if (touch_icon_helper_.get()) | 1446 if (touch_icon_helper_.get()) |
| 1547 touch_icon_helper_->FetchFavicon(details.entry->url()); | 1447 touch_icon_helper_->FetchFavicon(details.entry->url()); |
| 1548 | 1448 |
| 1549 // Clear all page actions, blocked content notifications and browser actions | 1449 // Clear all page actions, blocked content notifications and browser actions |
| 1550 // for this tab, unless this is an in-page navigation. | 1450 // for this tab, unless this is an in-page navigation. |
| 1551 if (!details.is_in_page) { | 1451 if (!details.is_in_page) { |
| 1552 // Close blocked popups. | |
| 1553 if (blocked_contents_) { | |
| 1554 blocked_contents_->Destroy(); | |
| 1555 blocked_contents_ = NULL; | |
| 1556 } | |
| 1557 | |
| 1558 // Clear "blocked" flags. | 1452 // Clear "blocked" flags. |
| 1559 content_settings_delegate_->ClearBlockedContentSettingsExceptForCookies(); | 1453 content_settings_delegate_->ClearBlockedContentSettingsExceptForCookies(); |
| 1560 content_settings_delegate_->GeolocationDidNavigate(details); | 1454 content_settings_delegate_->GeolocationDidNavigate(details); |
| 1561 | 1455 |
| 1562 // Once the main frame is navigated, we're no longer considered to have | 1456 // Once the main frame is navigated, we're no longer considered to have |
| 1563 // displayed insecure content. | 1457 // displayed insecure content. |
| 1564 displayed_insecure_content_ = false; | 1458 displayed_insecure_content_ = false; |
| 1565 } | 1459 } |
| 1566 | 1460 |
| 1567 // Close constrained windows if necessary. | 1461 // Close constrained windows if necessary. |
| (...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2544 | 2438 |
| 2545 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { | 2439 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { |
| 2546 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); | 2440 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); |
| 2547 rwh_view->SetSize(view()->GetContainerSize()); | 2441 rwh_view->SetSize(view()->GetContainerSize()); |
| 2548 } | 2442 } |
| 2549 | 2443 |
| 2550 void TabContents::OnOnlineStateChanged(bool online) { | 2444 void TabContents::OnOnlineStateChanged(bool online) { |
| 2551 render_view_host()->Send(new ViewMsg_NetworkStateChanged( | 2445 render_view_host()->Send(new ViewMsg_NetworkStateChanged( |
| 2552 render_view_host()->routing_id(), online)); | 2446 render_view_host()->routing_id(), online)); |
| 2553 } | 2447 } |
| OLD | NEW |