Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: content/browser/tab_contents/tab_contents.cc

Issue 6319001: Support window.opener after a process swap. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix unload; chrome dependency in RenderWidget. Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/command_line.h" 9 #include "base/command_line.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 // pending cross-site request, and then installs a CrossSiteEventHandler. 104 // pending cross-site request, and then installs a CrossSiteEventHandler.
105 // - When RDH receives a response, the BufferedEventHandler determines whether 105 // - When RDH receives a response, the BufferedEventHandler determines whether
106 // it is a download. If so, it sends a message to the new renderer causing 106 // it is a download. If so, it sends a message to the new renderer causing
107 // it to cancel the request, and the download proceeds in the download 107 // it to cancel the request, and the download proceeds in the download
108 // thread. For now, we stay in a PENDING state (with a pending RVH) until 108 // thread. For now, we stay in a PENDING state (with a pending RVH) until
109 // the next DidNavigate event for this TabContents. This isn't ideal, but it 109 // the next DidNavigate event for this TabContents. This isn't ideal, but it
110 // doesn't affect any functionality. 110 // doesn't affect any functionality.
111 // - After RDH receives a response and determines that it is safe and not a 111 // - After RDH receives a response and determines that it is safe and not a
112 // download, it pauses the response to first run the old page's onunload 112 // download, it pauses the response to first run the old page's onunload
113 // handler. It does this by asynchronously calling the OnCrossSiteResponse 113 // handler. It does this by asynchronously calling the OnCrossSiteResponse
114 // method of TabContents on the UI thread, which sends a ClosePage message 114 // method of TabContents on the UI thread, which sends a SwapOut message
115 // to the current RVH. 115 // to the current RVH.
116 // - Once the onunload handler is finished, a ClosePage_ACK message is sent to 116 // - Once the onunload handler is finished, a SwapOut_ACK message is sent to
117 // the ResourceDispatcherHost, who unpauses the response. Data is then sent 117 // the ResourceDispatcherHost, who unpauses the response. Data is then sent
118 // to the pending RVH. 118 // to the pending RVH.
119 // - The pending renderer sends a FrameNavigate message that invokes the 119 // - The pending renderer sends a FrameNavigate message that invokes the
120 // DidNavigate method. This replaces the current RVH with the 120 // DidNavigate method. This replaces the current RVH with the
121 // pending RVH and goes back to the NORMAL RendererState. 121 // pending RVH and goes back to the NORMAL RendererState.
122 // - The previous renderer is kept swapped out in RenderViewHostManager in case
123 // the user goes back. The process only stays live if another tab is using
124 // it, but if so, the existing frame relationships will be maintained.
122 125
123 namespace { 126 namespace {
124 127
125 // Amount of time we wait between when a key event is received and the renderer 128 // Amount of time we wait between when a key event is received and the renderer
126 // is queried for its state and pushed to the NavigationEntry. 129 // is queried for its state and pushed to the NavigationEntry.
127 const int kQueryStateDelay = 5000; 130 const int kQueryStateDelay = 5000;
128 131
129 const int kSyncWaitDelay = 40; 132 const int kSyncWaitDelay = 40;
130 133
131 // The list of prefs we want to observe. 134 // The list of prefs we want to observe.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 base_tab_contents->view()->GetContainerSize() : gfx::Size()); 255 base_tab_contents->view()->GetContainerSize() : gfx::Size());
253 256
254 // Register for notifications about all interested prefs change. 257 // Register for notifications about all interested prefs change.
255 PrefService* prefs = profile->GetPrefs(); 258 PrefService* prefs = profile->GetPrefs();
256 pref_change_registrar_.Init(prefs); 259 pref_change_registrar_.Init(prefs);
257 if (prefs) { 260 if (prefs) {
258 for (int i = 0; i < kPrefsToObserveLength; ++i) 261 for (int i = 0; i < kPrefsToObserveLength; ++i)
259 pref_change_registrar_.Add(kPrefsToObserve[i], this); 262 pref_change_registrar_.Add(kPrefsToObserve[i], this);
260 } 263 }
261 264
265 registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSING,
266 NotificationService::AllSources());
262 registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED, 267 registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DESTROYED,
263 NotificationService::AllSources()); 268 NotificationService::AllSources());
264 #if defined(OS_LINUX) 269 #if defined(OS_LINUX)
265 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, 270 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
266 NotificationService::AllSources()); 271 NotificationService::AllSources());
267 #endif 272 #endif
268 273
269 registrar_.Add(this, NotificationType::USER_STYLE_SHEET_UPDATED, 274 registrar_.Add(this, NotificationType::USER_STYLE_SHEET_UPDATED,
270 NotificationService::AllSources()); 275 NotificationService::AllSources());
271 276
(...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 1700
1696 // Run post-commit tasks. 1701 // Run post-commit tasks.
1697 if (details.is_main_frame) 1702 if (details.is_main_frame)
1698 DidNavigateMainFramePostCommit(details, params); 1703 DidNavigateMainFramePostCommit(details, params);
1699 DidNavigateAnyFramePostCommit(rvh, details, params); 1704 DidNavigateAnyFramePostCommit(rvh, details, params);
1700 } 1705 }
1701 1706
1702 void TabContents::UpdateState(RenderViewHost* rvh, 1707 void TabContents::UpdateState(RenderViewHost* rvh,
1703 int32 page_id, 1708 int32 page_id,
1704 const std::string& state) { 1709 const std::string& state) {
1705 DCHECK(rvh == render_view_host()); 1710 // Ensure that this state update comes from either the active RVH or one of
1711 // the swapped out RVHs. We don't expect to hear from any other RVHs.
1712 DCHECK(rvh == render_view_host() || render_manager_.IsSwappedOut(rvh));
1706 1713
1707 // We must be prepared to handle state updates for any page, these occur 1714 // We must be prepared to handle state updates for any page, these occur
1708 // when the user is scrolling and entering form data, as well as when we're 1715 // when the user is scrolling and entering form data, as well as when we're
1709 // leaving a page, in which case our state may have already been moved to 1716 // leaving a page, in which case our state may have already been moved to
1710 // the next page. The navigation controller will look up the appropriate 1717 // the next page. The navigation controller will look up the appropriate
1711 // NavigationEntry and update it when it is notified via the delegate. 1718 // NavigationEntry and update it when it is notified via the delegate.
1712 1719
1713 int entry_index = controller_.GetEntryIndexWithPageID( 1720 int entry_index = controller_.GetEntryIndexWithPageID(
1714 GetSiteInstance(), page_id); 1721 rvh->site_instance(), page_id);
1715 if (entry_index < 0) 1722 if (entry_index < 0)
1716 return; 1723 return;
1717 NavigationEntry* entry = controller_.GetEntryAtIndex(entry_index); 1724 NavigationEntry* entry = controller_.GetEntryAtIndex(entry_index);
1718 1725
1719 if (state == entry->content_state()) 1726 if (state == entry->content_state())
1720 return; // Nothing to update. 1727 return; // Nothing to update.
1721 entry->set_content_state(state); 1728 entry->set_content_state(state);
1722 controller_.NotifyEntryChanged(entry, entry_index); 1729 controller_.NotifyEntryChanged(entry, entry_index);
1723 } 1730 }
1724 1731
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 } 1873 }
1867 1874
1868 void TabContents::ProcessExternalHostMessage(const std::string& message, 1875 void TabContents::ProcessExternalHostMessage(const std::string& message,
1869 const std::string& origin, 1876 const std::string& origin,
1870 const std::string& target) { 1877 const std::string& target) {
1871 if (delegate()) 1878 if (delegate())
1872 delegate()->ForwardMessageToExternalHost(message, origin, target); 1879 delegate()->ForwardMessageToExternalHost(message, origin, target);
1873 } 1880 }
1874 1881
1875 void TabContents::RunJavaScriptMessage( 1882 void TabContents::RunJavaScriptMessage(
1883 const RenderViewHost* rvh,
1876 const std::wstring& message, 1884 const std::wstring& message,
1877 const std::wstring& default_prompt, 1885 const std::wstring& default_prompt,
1878 const GURL& frame_url, 1886 const GURL& frame_url,
1879 const int flags, 1887 const int flags,
1880 IPC::Message* reply_msg, 1888 IPC::Message* reply_msg,
1881 bool* did_suppress_message) { 1889 bool* did_suppress_message) {
1882 // Suppress javascript messages when requested and when inside a constrained 1890 // Suppress javascript messages when requested and when inside a constrained
1883 // popup window (because that activates them and breaks them out of the 1891 // popup window (because that activates them and breaks them out of the
1884 // constrained window jail). 1892 // constrained window jail).
1885 // Also suppress messages when showing an interstitial. The interstitial is 1893 // Also suppress messages when showing an interstitial. The interstitial is
1886 // shown over the previous page, we don't want the hidden page dialogs to 1894 // shown over the previous page, we don't want the hidden page dialogs to
1887 // interfere with the interstitial. 1895 // interfere with the interstitial.
1888 bool suppress_this_message = 1896 bool suppress_this_message =
1897 rvh->is_swapped_out() ||
1889 suppress_javascript_messages_ || 1898 suppress_javascript_messages_ ||
1890 showing_interstitial_page() || 1899 showing_interstitial_page() ||
1891 (delegate() && delegate()->ShouldSuppressDialogs()); 1900 (delegate() && delegate()->ShouldSuppressDialogs());
1892 if (delegate()) 1901 if (delegate())
1893 suppress_this_message |= 1902 suppress_this_message |=
1894 (delegate()->GetConstrainingContents(this) != this); 1903 (delegate()->GetConstrainingContents(this) != this);
1895 1904
1896 *did_suppress_message = suppress_this_message; 1905 *did_suppress_message = suppress_this_message;
1897 1906
1898 if (!suppress_this_message) { 1907 if (!suppress_this_message) {
1899 base::TimeDelta time_since_last_message( 1908 base::TimeDelta time_since_last_message(
1900 base::TimeTicks::Now() - last_javascript_message_dismissal_); 1909 base::TimeTicks::Now() - last_javascript_message_dismissal_);
1901 bool show_suppress_checkbox = false; 1910 bool show_suppress_checkbox = false;
1902 // Show a checkbox offering to suppress further messages if this message is 1911 // Show a checkbox offering to suppress further messages if this message is
1903 // being displayed within kJavascriptMessageExpectedDelay of the last one. 1912 // being displayed within kJavascriptMessageExpectedDelay of the last one.
1904 if (time_since_last_message < 1913 if (time_since_last_message <
1905 base::TimeDelta::FromMilliseconds( 1914 base::TimeDelta::FromMilliseconds(
1906 chrome::kJavascriptMessageExpectedDelay)) 1915 chrome::kJavascriptMessageExpectedDelay))
1907 show_suppress_checkbox = true; 1916 show_suppress_checkbox = true;
1908 1917
1909 RunJavascriptMessageBox(profile(), this, frame_url, flags, message, 1918 RunJavascriptMessageBox(profile(), this, frame_url, flags, message,
1910 default_prompt, show_suppress_checkbox, reply_msg); 1919 default_prompt, show_suppress_checkbox, reply_msg);
1911 } else { 1920 } else {
1912 // If we are suppressing messages, just reply as is if the user immediately 1921 // If we are suppressing messages, just reply as is if the user immediately
1913 // pressed "Cancel". 1922 // pressed "Cancel".
1914 OnMessageBoxClosed(reply_msg, false, std::wstring()); 1923 OnMessageBoxClosed(reply_msg, false, std::wstring());
1915 } 1924 }
1916 } 1925 }
1917 1926
1918 void TabContents::RunBeforeUnloadConfirm(const std::wstring& message, 1927 void TabContents::RunBeforeUnloadConfirm(const RenderViewHost* rvh,
1928 const std::wstring& message,
1919 IPC::Message* reply_msg) { 1929 IPC::Message* reply_msg) {
1920 if (delegate()) 1930 if (delegate())
1921 delegate()->WillRunBeforeUnloadConfirm(); 1931 delegate()->WillRunBeforeUnloadConfirm();
1922 if (delegate() && delegate()->ShouldSuppressDialogs()) { 1932 bool suppress_this_message = rvh->is_swapped_out() ||
1933 (delegate() && delegate()->ShouldSuppressDialogs());
1934 if (suppress_this_message) {
1923 render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true, 1935 render_view_host()->JavaScriptMessageBoxClosed(reply_msg, true,
1924 std::wstring()); 1936 std::wstring());
1925 return; 1937 return;
1926 } 1938 }
1927 is_showing_before_unload_dialog_ = true; 1939 is_showing_before_unload_dialog_ = true;
1928 RunBeforeUnloadDialog(this, message, reply_msg); 1940 RunBeforeUnloadDialog(this, message, reply_msg);
1929 } 1941 }
1930 1942
1931 GURL TabContents::GetAlternateErrorPageURL() const { 1943 GURL TabContents::GetAlternateErrorPageURL() const {
1932 return content::GetContentClient()->browser()->GetAlternateErrorPageURL(this); 1944 return content::GetContentClient()->browser()->GetAlternateErrorPageURL(this);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 int new_request_id) { 1988 int new_request_id) {
1977 // Allows the TabContents to react when a cross-site response is ready to be 1989 // Allows the TabContents to react when a cross-site response is ready to be
1978 // delivered to a pending RenderViewHost. We must first run the onunload 1990 // delivered to a pending RenderViewHost. We must first run the onunload
1979 // handler of the old RenderViewHost before we can allow it to proceed. 1991 // handler of the old RenderViewHost before we can allow it to proceed.
1980 render_manager_.OnCrossSiteResponse(new_render_process_host_id, 1992 render_manager_.OnCrossSiteResponse(new_render_process_host_id,
1981 new_request_id); 1993 new_request_id);
1982 } 1994 }
1983 1995
1984 void TabContents::RendererUnresponsive(RenderViewHost* rvh, 1996 void TabContents::RendererUnresponsive(RenderViewHost* rvh,
1985 bool is_during_unload) { 1997 bool is_during_unload) {
1998 // Don't show hung renderer dialog for a swapped out RVH.
1999 if (rvh != render_view_host())
2000 return;
2001
1986 if (is_during_unload) { 2002 if (is_during_unload) {
1987 // Hang occurred while firing the beforeunload/unload handler. 2003 // Hang occurred while firing the beforeunload/unload handler.
1988 // Pretend the handler fired so tab closing continues as if it had. 2004 // Pretend the handler fired so tab closing continues as if it had.
1989 rvh->set_sudden_termination_allowed(true); 2005 rvh->set_sudden_termination_allowed(true);
1990 2006
1991 if (!render_manager_.ShouldCloseTabOnUnresponsiveRenderer()) 2007 if (!render_manager_.ShouldCloseTabOnUnresponsiveRenderer())
1992 return; 2008 return;
1993 2009
1994 // If the tab hangs in the beforeunload/unload handler there's really 2010 // If the tab hangs in the beforeunload/unload handler there's really
1995 // nothing we can do to recover. Pretend the unload listeners have 2011 // nothing we can do to recover. Pretend the unload listeners have
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 UpdateZoomLevel(); 2157 UpdateZoomLevel();
2142 } else if (*pref_name_in == prefs::kEnableReferrers) { 2158 } else if (*pref_name_in == prefs::kEnableReferrers) {
2143 renderer_preferences_util::UpdateFromSystemSettings( 2159 renderer_preferences_util::UpdateFromSystemSettings(
2144 &renderer_preferences_, profile()); 2160 &renderer_preferences_, profile());
2145 render_view_host()->SyncRendererPrefs(); 2161 render_view_host()->SyncRendererPrefs();
2146 } else { 2162 } else {
2147 NOTREACHED() << "unexpected pref change notification" << *pref_name_in; 2163 NOTREACHED() << "unexpected pref change notification" << *pref_name_in;
2148 } 2164 }
2149 break; 2165 break;
2150 } 2166 }
2167 case NotificationType::RENDERER_PROCESS_CLOSING:
2168 render_manager_.RendererProcessClosing(
2169 Source<RenderProcessHost>(source).ptr());
2170 break;
2171
2151 case NotificationType::RENDER_WIDGET_HOST_DESTROYED: 2172 case NotificationType::RENDER_WIDGET_HOST_DESTROYED:
2152 view_->RenderWidgetHostDestroyed(Source<RenderWidgetHost>(source).ptr()); 2173 view_->RenderWidgetHostDestroyed(Source<RenderWidgetHost>(source).ptr());
2153 break; 2174 break;
2154 2175
2155 case NotificationType::NAV_ENTRY_COMMITTED: { 2176 case NotificationType::NAV_ENTRY_COMMITTED: {
2156 DCHECK(&controller_ == Source<NavigationController>(source).ptr()); 2177 DCHECK(&controller_ == Source<NavigationController>(source).ptr());
2157 2178
2158 NavigationController::LoadCommittedDetails& committed_details = 2179 NavigationController::LoadCommittedDetails& committed_details =
2159 *(Details<NavigationController::LoadCommittedDetails>(details).ptr()); 2180 *(Details<NavigationController::LoadCommittedDetails>(details).ptr());
2160 ExpireInfoBars(committed_details); 2181 ExpireInfoBars(committed_details);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2240 2261
2241 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) { 2262 void TabContents::CreateViewAndSetSizeForRVH(RenderViewHost* rvh) {
2242 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh); 2263 RenderWidgetHostView* rwh_view = view()->CreateViewForWidget(rvh);
2243 rwh_view->SetSize(view()->GetContainerSize()); 2264 rwh_view->SetSize(view()->GetContainerSize());
2244 } 2265 }
2245 2266
2246 void TabContents::OnOnlineStateChanged(bool online) { 2267 void TabContents::OnOnlineStateChanged(bool online) {
2247 render_view_host()->Send(new ViewMsg_NetworkStateChanged( 2268 render_view_host()->Send(new ViewMsg_NetworkStateChanged(
2248 render_view_host()->routing_id(), online)); 2269 render_view_host()->routing_id(), online));
2249 } 2270 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698