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

Side by Side Diff: content/browser/frame_host/render_frame_host_manager_unittest.cc

Issue 196133032: Add test for filtering of IPC messages when RenderFrameHost is swapped out. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add a test bypassing OnCrossSiteResponse. Created 6 years, 9 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 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 "base/files/file_path.h"
5 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
6 #include "content/browser/frame_host/cross_site_transferring_request.h" 7 #include "content/browser/frame_host/cross_site_transferring_request.h"
7 #include "content/browser/frame_host/navigation_controller_impl.h" 8 #include "content/browser/frame_host/navigation_controller_impl.h"
8 #include "content/browser/frame_host/navigation_entry_impl.h" 9 #include "content/browser/frame_host/navigation_entry_impl.h"
9 #include "content/browser/frame_host/navigator.h" 10 #include "content/browser/frame_host/navigator.h"
10 #include "content/browser/frame_host/render_frame_host_manager.h" 11 #include "content/browser/frame_host/render_frame_host_manager.h"
11 #include "content/browser/site_instance_impl.h" 12 #include "content/browser/site_instance_impl.h"
12 #include "content/browser/webui/web_ui_controller_factory_registry.h" 13 #include "content/browser/webui/web_ui_controller_factory_registry.h"
13 #include "content/common/frame_messages.h" 14 #include "content/common/frame_messages.h"
14 #include "content/common/view_messages.h" 15 #include "content/common/view_messages.h"
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 virtual void BeforeUnloadFired(WebContents* web_contents, 87 virtual void BeforeUnloadFired(WebContents* web_contents,
87 bool proceed, 88 bool proceed,
88 bool* proceed_to_fire_unload) OVERRIDE { 89 bool* proceed_to_fire_unload) OVERRIDE {
89 *proceed_to_fire_unload = proceed; 90 *proceed_to_fire_unload = proceed;
90 } 91 }
91 92
92 private: 93 private:
93 DISALLOW_COPY_AND_ASSIGN(BeforeUnloadFiredWebContentsDelegate); 94 DISALLOW_COPY_AND_ASSIGN(BeforeUnloadFiredWebContentsDelegate);
94 }; 95 };
95 96
97 // This observer keeps track of the last deleted RenderViewHost to avoid
98 // accessing it and causing use-after-free condition.
99 class RenderViewHostDeletedObserver : public WebContentsObserver {
100 public:
101 RenderViewHostDeletedObserver(RenderViewHost* rvh)
102 : WebContentsObserver(WebContents::FromRenderViewHost(rvh)),
103 process_id_(rvh->GetProcess()->GetID()),
104 routing_id_(rvh->GetRoutingID()),
105 render_view_host_(rvh),
106 deleted_(false) {
107 }
108
109 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE {
110 if (render_view_host->GetProcess()->GetID() == process_id_ &&
111 render_view_host->GetRoutingID() == routing_id_) {
112 // The expectation is that the pointers are exactly the same, but the
113 // pointers shouldn't be used, as the object is destroyed.
Charlie Reis 2014/03/24 23:24:43 I don't understand this comment. It says we shoul
nasko 2014/03/25 18:30:22 Ok, got back to not using pointers. The aim of thi
114 EXPECT_EQ(render_view_host_, render_view_host);
115 render_view_host_ = NULL;
116 deleted_ = true;
117 }
118 }
119
120 bool deleted() {
121 return deleted_;
122 }
123
124 private:
125 int process_id_;
126 int routing_id_;
127 RenderViewHost* render_view_host_;
128 bool deleted_;
129
130 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDeletedObserver);
131 };
132
133
134 // This observer is used to check whether IPC messages are being filtered for
135 // swapped out RenderFrameHost objects. It observes the plugin crash and favicon
136 // update events, which the FilterMessagesWhileSwappedOut test simulates being
137 // sent. The test is successful if the event is not observed.
138 // See http://crbug.com/351815
139 class PluginFaviconMessageObserver : public WebContentsObserver {
140 public:
141 PluginFaviconMessageObserver(WebContents* web_contents)
142 : WebContentsObserver(web_contents),
143 plugin_crashed_(false),
144 favicon_received_(false) { }
145
146 virtual void PluginCrashed(const base::FilePath& plugin_path,
147 base::ProcessId plugin_pid) OVERRIDE {
148 plugin_crashed_ = true;
149 }
150
151 virtual void DidUpdateFaviconURL(
152 int32 page_id,
153 const std::vector<FaviconURL>& candidates) OVERRIDE {
154 favicon_received_ = true;
155 }
156
157 bool plugin_crashed() {
158 return plugin_crashed_;
159 }
160
161 bool favicon_received() {
162 return favicon_received_;
163 }
164
165 private:
166 bool plugin_crashed_;
167 bool favicon_received_;
168
169 DISALLOW_COPY_AND_ASSIGN(PluginFaviconMessageObserver);
170 };
171
172
96 } // namespace 173 } // namespace
97 174
98 class RenderFrameHostManagerTest 175 class RenderFrameHostManagerTest
99 : public RenderViewHostImplTestHarness { 176 : public RenderViewHostImplTestHarness {
100 public: 177 public:
101 virtual void SetUp() OVERRIDE { 178 virtual void SetUp() OVERRIDE {
102 RenderViewHostImplTestHarness::SetUp(); 179 RenderViewHostImplTestHarness::SetUp();
103 WebUIControllerFactory::RegisterFactory(&factory_); 180 WebUIControllerFactory::RegisterFactory(&factory_);
104 } 181 }
105 182
106 virtual void TearDown() OVERRIDE { 183 virtual void TearDown() OVERRIDE {
107 RenderViewHostImplTestHarness::TearDown(); 184 RenderViewHostImplTestHarness::TearDown();
108 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_); 185 WebUIControllerFactory::UnregisterFactoryForTesting(&factory_);
109 } 186 }
110 187
111 void set_should_create_webui(bool should_create_webui) { 188 void set_should_create_webui(bool should_create_webui) {
112 factory_.set_should_create_webui(should_create_webui); 189 factory_.set_should_create_webui(should_create_webui);
113 } 190 }
114 191
192 void StartCrossSiteTransition(TestWebContents* contents) {
193 std::vector<GURL> url_chain;
194 url_chain.push_back(GURL());
195 contents->GetRenderManagerForTesting()->OnCrossSiteResponse(
196 contents->GetRenderManagerForTesting()->pending_frame_host(),
197 GlobalRequestID(0, 0), scoped_ptr<CrossSiteTransferringRequest>(),
198 url_chain, Referrer(), PAGE_TRANSITION_TYPED, false);
199 EXPECT_TRUE(contents->cross_navigation_pending());
200 RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
201 contents->GetRenderViewHost());
202 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_UNLOAD_ACK,
203 rvh->rvh_state());
204 }
205
115 void NavigateActiveAndCommit(const GURL& url) { 206 void NavigateActiveAndCommit(const GURL& url) {
116 // Note: we navigate the active RenderViewHost because previous navigations 207 // Note: we navigate the active RenderViewHost because previous navigations
117 // won't have committed yet, so NavigateAndCommit does the wrong thing 208 // won't have committed yet, so NavigateAndCommit does the wrong thing
118 // for us. 209 // for us.
119 controller().LoadURL(url, Referrer(), PAGE_TRANSITION_LINK, std::string()); 210 controller().LoadURL(url, Referrer(), PAGE_TRANSITION_LINK, std::string());
120 TestRenderViewHost* old_rvh = test_rvh(); 211 TestRenderViewHost* old_rvh = test_rvh();
121 212
122 // Simulate the BeforeUnload_ACK that is received from the current renderer 213 // Simulate the BeforeUnload_ACK that is received from the current renderer
123 // for a cross-site navigation. 214 // for a cross-site navigation.
124 if (old_rvh != active_rvh()) 215 if (old_rvh != active_rvh()) {
125 old_rvh->SendBeforeUnloadACK(true); 216 old_rvh->SendBeforeUnloadACK(true);
217 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, old_rvh->rvh_state());
218 }
126 219
127 // Commit the navigation with a new page ID. 220 // Commit the navigation with a new page ID.
128 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance( 221 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance(
129 active_rvh()->GetSiteInstance()); 222 active_rvh()->GetSiteInstance());
130 223
224 // Simulate the response comming from the pending renderer.
225 if (old_rvh != active_rvh())
226 StartCrossSiteTransition(contents());
227
131 // Simulate the SwapOut_ACK that fires if you commit a cross-site 228 // Simulate the SwapOut_ACK that fires if you commit a cross-site
132 // navigation. 229 // navigation.
133 if (old_rvh != active_rvh()) 230 if (old_rvh != active_rvh()) {
134 old_rvh->OnSwappedOut(false); 231 old_rvh->OnSwappedOut(false);
232 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT,
233 old_rvh->rvh_state());
234 }
135 235
236 // Use an observer to avoid accessing a deleted renderer later on when the
237 // state is being checked.
238 RenderViewHostDeletedObserver rvh_observer(old_rvh);
136 active_test_rvh()->SendNavigate(max_page_id + 1, url); 239 active_test_rvh()->SendNavigate(max_page_id + 1, url);
240
241 if (old_rvh != active_rvh() && !rvh_observer.deleted())
242 EXPECT_TRUE(old_rvh->IsSwappedOut());
137 } 243 }
138 244
139 bool ShouldSwapProcesses(RenderFrameHostManager* manager, 245 bool ShouldSwapProcesses(RenderFrameHostManager* manager,
140 const NavigationEntryImpl* current_entry, 246 const NavigationEntryImpl* current_entry,
141 const NavigationEntryImpl* new_entry) const { 247 const NavigationEntryImpl* new_entry) const {
142 return manager->ShouldSwapBrowsingInstancesForNavigation(current_entry, 248 return manager->ShouldSwapBrowsingInstancesForNavigation(current_entry,
143 new_entry); 249 new_entry);
144 } 250 }
145 251
146 // Creates a test RenderViewHost that's swapped out. 252 // Creates a test RenderViewHost that's swapped out.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 // The second one is the opposite, creating a cross-site transition and 321 // The second one is the opposite, creating a cross-site transition and
216 // requiring a beforeunload ack. 322 // requiring a beforeunload ack.
217 contents2->GetController().LoadURL( 323 contents2->GetController().LoadURL(
218 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); 324 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string());
219 EXPECT_TRUE(contents2->cross_navigation_pending()); 325 EXPECT_TRUE(contents2->cross_navigation_pending());
220 TestRenderViewHost* dest_rvh2 = static_cast<TestRenderViewHost*>( 326 TestRenderViewHost* dest_rvh2 = static_cast<TestRenderViewHost*>(
221 contents2->GetRenderManagerForTesting()->pending_render_view_host()); 327 contents2->GetRenderManagerForTesting()->pending_render_view_host());
222 ASSERT_TRUE(dest_rvh2); 328 ASSERT_TRUE(dest_rvh2);
223 329
224 ntp_rvh2->SendBeforeUnloadACK(true); 330 ntp_rvh2->SendBeforeUnloadACK(true);
225 ntp_rvh2->OnSwappedOut(false); 331 StartCrossSiteTransition(contents2.get());
226 dest_rvh2->SendNavigate(101, kDestUrl); 332 dest_rvh2->SendNavigate(101, kDestUrl);
227 333
228 // The two RVH's should be different in every way. 334 // The two RVH's should be different in every way.
229 EXPECT_NE(active_rvh()->GetProcess(), dest_rvh2->GetProcess()); 335 EXPECT_NE(active_rvh()->GetProcess(), dest_rvh2->GetProcess());
230 EXPECT_NE(active_rvh()->GetSiteInstance(), dest_rvh2->GetSiteInstance()); 336 EXPECT_NE(active_rvh()->GetSiteInstance(), dest_rvh2->GetSiteInstance());
231 EXPECT_FALSE(active_rvh()->GetSiteInstance()->IsRelatedSiteInstance( 337 EXPECT_FALSE(active_rvh()->GetSiteInstance()->IsRelatedSiteInstance(
232 dest_rvh2->GetSiteInstance())); 338 dest_rvh2->GetSiteInstance()));
233 339
234 // Navigate both to the new tab page, and verify that they share a 340 // Navigate both to the new tab page, and verify that they share a
235 // RenderProcessHost (not a SiteInstance). 341 // RenderProcessHost (not a SiteInstance).
236 NavigateActiveAndCommit(kChromeUrl); 342 NavigateActiveAndCommit(kChromeUrl);
237 343
238 contents2->GetController().LoadURL( 344 contents2->GetController().LoadURL(
239 kChromeUrl, Referrer(), PAGE_TRANSITION_LINK, std::string()); 345 kChromeUrl, Referrer(), PAGE_TRANSITION_LINK, std::string());
240 dest_rvh2->SendBeforeUnloadACK(true); 346 dest_rvh2->SendBeforeUnloadACK(true);
241 dest_rvh2->OnSwappedOut(false); 347 StartCrossSiteTransition(contents2.get());
242 static_cast<TestRenderViewHost*>(contents2->GetRenderManagerForTesting()-> 348 static_cast<TestRenderViewHost*>(contents2->GetRenderManagerForTesting()->
243 pending_render_view_host())->SendNavigate(102, kChromeUrl); 349 pending_render_view_host())->SendNavigate(102, kChromeUrl);
244 350
245 EXPECT_NE(active_rvh()->GetSiteInstance(), 351 EXPECT_NE(active_rvh()->GetSiteInstance(),
246 contents2->GetRenderViewHost()->GetSiteInstance()); 352 contents2->GetRenderViewHost()->GetSiteInstance());
247 EXPECT_EQ(active_rvh()->GetSiteInstance()->GetProcess(), 353 EXPECT_EQ(active_rvh()->GetSiteInstance()->GetProcess(),
248 contents2->GetRenderViewHost()->GetSiteInstance()->GetProcess()); 354 contents2->GetRenderViewHost()->GetSiteInstance()->GetProcess());
249 } 355 }
250 356
251 // Ensure that the browser ignores most IPC messages that arrive from a 357 // Ensure that the browser ignores most IPC messages that arrive from a
252 // RenderViewHost that has been swapped out. We do not want to take 358 // RenderViewHost that has been swapped out. We do not want to take
253 // action on requests from a non-active renderer. The main exception is 359 // action on requests from a non-active renderer. The main exception is
254 // for synchronous messages, which cannot be ignored without leaving the 360 // for synchronous messages, which cannot be ignored without leaving the
255 // renderer in a stuck state. See http://crbug.com/93427. 361 // renderer in a stuck state. See http://crbug.com/93427.
256 TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) { 362 TEST_F(RenderFrameHostManagerTest, FilterMessagesWhileSwappedOut) {
257 const GURL kChromeURL("chrome://foo"); 363 const GURL kChromeURL("chrome://foo");
258 const GURL kDestUrl("http://www.google.com/"); 364 const GURL kDestUrl("http://www.google.com/");
365 std::vector<FaviconURL> icons;
259 366
260 // Navigate our first tab to a chrome url and then to the destination. 367 // Navigate our first tab to a chrome url and then to the destination.
261 NavigateActiveAndCommit(kChromeURL); 368 NavigateActiveAndCommit(kChromeURL);
262 TestRenderViewHost* ntp_rvh = static_cast<TestRenderViewHost*>( 369 TestRenderViewHost* ntp_rvh = static_cast<TestRenderViewHost*>(
263 contents()->GetRenderManagerForTesting()->current_host()); 370 contents()->GetRenderManagerForTesting()->current_host());
264 371
265 // Send an update title message and make sure it works. 372 // Send an update favicon message and make sure it works.
266 const base::string16 ntp_title = base::ASCIIToUTF16("NTP Title"); 373 const base::string16 ntp_title = base::ASCIIToUTF16("NTP Title");
267 blink::WebTextDirection direction = blink::WebTextDirectionLeftToRight; 374 {
268 EXPECT_TRUE(ntp_rvh->OnMessageReceived( 375 PluginFaviconMessageObserver observer(contents());
269 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction))); 376 EXPECT_TRUE(ntp_rvh->OnMessageReceived(
270 EXPECT_EQ(ntp_title, contents()->GetTitle()); 377 ViewHostMsg_UpdateFaviconURL(
271 378 rvh()->GetRoutingID(), 0, icons)));
272 // Navigate to a cross-site URL. 379 EXPECT_TRUE(observer.favicon_received());
273 contents()->GetController().LoadURL( 380 }
274 kDestUrl, Referrer(), PAGE_TRANSITION_LINK, std::string());
275 EXPECT_TRUE(contents()->cross_navigation_pending());
276 TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>(
277 contents()->GetRenderManagerForTesting()->pending_render_view_host());
278 ASSERT_TRUE(dest_rvh);
279 EXPECT_NE(ntp_rvh, dest_rvh);
280
281 // Create one more view in the same SiteInstance where dest_rvh2 381 // Create one more view in the same SiteInstance where dest_rvh2
282 // exists so that it doesn't get deleted on navigation to another 382 // exists so that it doesn't get deleted on navigation to another
283 // site. 383 // site.
284 static_cast<SiteInstanceImpl*>(ntp_rvh->GetSiteInstance())-> 384 static_cast<SiteInstanceImpl*>(ntp_rvh->GetSiteInstance())->
285 increment_active_view_count(); 385 increment_active_view_count();
286 386
287 // BeforeUnload finishes.
288 ntp_rvh->SendBeforeUnloadACK(true);
289 387
290 // Assume SwapOutACK times out, so the dest_rvh proceeds and commits. 388 // Navigate to a cross-site URL.
291 dest_rvh->SendNavigate(101, kDestUrl); 389 NavigateActiveAndCommit(kDestUrl);
390 TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>(
391 contents()->GetRenderViewHost());
392 ASSERT_TRUE(dest_rvh);
393 EXPECT_NE(ntp_rvh, dest_rvh);
292 394
293 // The new RVH should be able to update its title. 395 // The new RVH should be able to update its favicon.
294 const base::string16 dest_title = base::ASCIIToUTF16("Google"); 396 const base::string16 dest_title = base::ASCIIToUTF16("Google");
295 EXPECT_TRUE(dest_rvh->OnMessageReceived( 397 {
296 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 101, dest_title, 398 PluginFaviconMessageObserver observer(contents());
297 direction))); 399 EXPECT_TRUE(
298 EXPECT_EQ(dest_title, contents()->GetTitle()); 400 dest_rvh->OnMessageReceived(
401 ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), 101, icons)));
402 EXPECT_TRUE(observer.favicon_received());
403 }
299 404
300 // The old renderer, being slow, now updates the title. It should be filtered 405 // The old renderer, being slow, now updates the favicon. It should be
301 // out and not take effect. 406 // filtered out and not take effect.
302 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, ntp_rvh->rvh_state()); 407 EXPECT_TRUE(ntp_rvh->IsSwappedOut());
303 EXPECT_TRUE(ntp_rvh->OnMessageReceived( 408 {
304 ViewHostMsg_UpdateTitle(rvh()->GetRoutingID(), 0, ntp_title, direction))); 409 PluginFaviconMessageObserver observer(contents());
305 EXPECT_EQ(dest_title, contents()->GetTitle()); 410 EXPECT_TRUE(
411 ntp_rvh->OnMessageReceived(
412 ViewHostMsg_UpdateFaviconURL(rvh()->GetRoutingID(), 101, icons)));
413 EXPECT_FALSE(observer.favicon_received());
414 }
415
416 // The same logic should apply to RenderFrameHosts as well and routing through
417 // swapped out RFH shouldn't be allowed. Use a PluginCrashObserver to check
418 // if the IPC message is allowed through or not.
419 {
420 PluginFaviconMessageObserver observer(contents());
421 // TODO(nasko): Check that the RFH is in swapped out when the state moves
422 // from RVH to RFH.
423 EXPECT_TRUE(ntp_rvh->main_render_frame_host()->OnMessageReceived(
424 FrameHostMsg_PluginCrashed(
425 main_rfh()->GetRoutingID(), base::FilePath(), 0)));
426 EXPECT_FALSE(observer.plugin_crashed());
427 }
306 428
307 // We cannot filter out synchronous IPC messages, because the renderer would 429 // We cannot filter out synchronous IPC messages, because the renderer would
308 // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example 430 // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example
309 // that can run easily within a unit test, and that needs to receive a reply 431 // that can run easily within a unit test, and that needs to receive a reply
310 // without showing an actual dialog. 432 // without showing an actual dialog.
311 MockRenderProcessHost* ntp_process_host = 433 MockRenderProcessHost* ntp_process_host =
312 static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess()); 434 static_cast<MockRenderProcessHost*>(ntp_rvh->GetProcess());
313 ntp_process_host->sink().ClearMessages(); 435 ntp_process_host->sink().ClearMessages();
314 const base::string16 msg = base::ASCIIToUTF16("Message"); 436 const base::string16 msg = base::ASCIIToUTF16("Message");
315 bool result = false; 437 bool result = false;
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 EXPECT_EQ(host, manager->current_frame_host()); 928 EXPECT_EQ(host, manager->current_frame_host());
807 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out()); 929 EXPECT_FALSE(manager->current_frame_host()->is_swapped_out());
808 930
809 // Simulate a response to the second beforeunload request. 931 // Simulate a response to the second beforeunload request.
810 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( 932 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching(
811 FrameMsg_BeforeUnload::ID)); 933 FrameMsg_BeforeUnload::ID));
812 test_host->SendBeforeUnloadACK(true); 934 test_host->SendBeforeUnloadACK(true);
813 935
814 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a 936 // CrossSiteResourceHandler::StartCrossSiteTransition triggers a
815 // call of RenderFrameHostManager::SwapOutOldPage before 937 // call of RenderFrameHostManager::SwapOutOldPage before
816 // RenderFrameHostManager::DidNavigateFrame is called. 938 // RenderFrameHostManager::DidNavigateFrame is called. Since the previous
939 // navigation has already cause the renderer to start swapping out, there
940 // will be no more SwapOut messages being sent.
817 manager->SwapOutOldPage(); 941 manager->SwapOutOldPage();
818 EXPECT_TRUE(test_process_host->sink().GetUniqueMessageMatching( 942 EXPECT_FALSE(test_process_host->sink().GetUniqueMessageMatching(
819 ViewMsg_SwapOut::ID)); 943 ViewMsg_SwapOut::ID));
820 test_host->OnSwappedOut(false); 944 test_host->OnSwappedOut(false);
821 945
822 // Commit. 946 // Commit.
823 manager->DidNavigateFrame(host3); 947 manager->DidNavigateFrame(host3);
824 EXPECT_TRUE(host3 == manager->current_frame_host()); 948 EXPECT_TRUE(host3 == manager->current_frame_host());
825 ASSERT_TRUE(host3); 949 ASSERT_TRUE(host3);
826 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host3->GetSiteInstance())-> 950 EXPECT_TRUE(static_cast<SiteInstanceImpl*>(host3->GetSiteInstance())->
827 HasSite()); 951 HasSite());
828 // Check the pending RenderFrameHost has been committed. 952 // Check the pending RenderFrameHost has been committed.
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())-> 1146 static_cast<SiteInstanceImpl*>(rvh2->GetSiteInstance())->
1023 increment_active_view_count(); 1147 increment_active_view_count();
1024 1148
1025 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't 1149 // Now go back, but suppose the SwapOut_ACK isn't received. This shouldn't
1026 // happen, but we have seen it when going back quickly across many entries 1150 // happen, but we have seen it when going back quickly across many entries
1027 // (http://crbug.com/93427). 1151 // (http://crbug.com/93427).
1028 contents()->GetController().GoBack(); 1152 contents()->GetController().GoBack();
1029 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack()); 1153 EXPECT_TRUE(rvh2->is_waiting_for_beforeunload_ack());
1030 contents()->ProceedWithCrossSiteNavigation(); 1154 contents()->ProceedWithCrossSiteNavigation();
1031 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack()); 1155 EXPECT_FALSE(rvh2->is_waiting_for_beforeunload_ack());
1032 rvh2->SwapOut(); 1156 StartCrossSiteTransition(contents());
1033 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK()); 1157 EXPECT_TRUE(rvh2->IsWaitingForUnloadACK());
1034 1158
1035 // The back navigation commits. 1159 // The back navigation commits.
1036 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); 1160 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry();
1037 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); 1161 rvh1->SendNavigate(entry1->GetPageID(), entry1->GetURL());
1038 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state()); 1162 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh2->rvh_state());
1039 1163
1040 // We should be able to navigate forward. 1164 // We should be able to navigate forward.
1041 contents()->GetController().GoForward(); 1165 contents()->GetController().GoForward();
1042 contents()->ProceedWithCrossSiteNavigation(); 1166 contents()->ProceedWithCrossSiteNavigation();
1167 StartCrossSiteTransition(contents());
1043 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); 1168 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry();
1044 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); 1169 rvh2->SendNavigate(entry2->GetPageID(), entry2->GetURL());
1045 EXPECT_EQ(rvh2, rvh()); 1170 EXPECT_EQ(rvh2, rvh());
1046 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); 1171 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1047 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state()); 1172 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
1048 rvh1->OnSwappedOut(false); 1173 rvh1->OnSwappedOut(false);
1049 EXPECT_TRUE(rvh1->IsSwappedOut()); 1174 EXPECT_TRUE(rvh1->IsSwappedOut());
1050 } 1175 }
1051 1176
1052 // Test that we create swapped out RVHs for the opener chain when navigating an 1177 // Test that we create swapped out RVHs for the opener chain when navigating an
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 1465 notifications.ListenFor(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
1341 Source<RenderWidgetHost>(host2->render_view_host())); 1466 Source<RenderWidgetHost>(host2->render_view_host()));
1342 manager->OnBeforeUnloadACK(false, true, base::TimeTicks()); 1467 manager->OnBeforeUnloadACK(false, true, base::TimeTicks());
1343 1468
1344 EXPECT_TRUE( 1469 EXPECT_TRUE(
1345 notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED)); 1470 notifications.Check1AndReset(NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED));
1346 EXPECT_FALSE(manager->pending_frame_host()); 1471 EXPECT_FALSE(manager->pending_frame_host());
1347 EXPECT_EQ(host, manager->current_frame_host()); 1472 EXPECT_EQ(host, manager->current_frame_host());
1348 } 1473 }
1349 1474
1350 // This checks that the given RVH has been properly deleted.
1351 class RenderViewHostDestructionObserver : public WebContentsObserver {
1352 public:
1353 RenderViewHostDestructionObserver(RenderViewHost* render_view_host)
1354 : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)),
1355 render_view_host_(render_view_host),
1356 rvh_deleted_(false) {}
1357
1358 bool rvh_deleted() { return rvh_deleted_; }
1359
1360 virtual void RenderViewDeleted(RenderViewHost* render_view_host) OVERRIDE {
1361 if (render_view_host == render_view_host_)
1362 rvh_deleted_ = true;
1363 }
1364
1365 private:
1366 RenderViewHost* render_view_host_;
1367 bool rvh_deleted_;
1368
1369 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver);
1370 };
1371
1372 // Tests that the RenderViewHost is properly deleted when the SwapOutACK is 1475 // Tests that the RenderViewHost is properly deleted when the SwapOutACK is
1373 // received before the new page commits. 1476 // received before the new page commits.
1374 TEST_F(RenderFrameHostManagerTest, 1477 TEST_F(RenderFrameHostManagerTest,
1375 SwapOutACKBeforeNewPageCommitsLeadsToDeletion) { 1478 SwapOutACKBeforeNewPageCommitsLeadsToDeletion) {
1376 const GURL kUrl1("http://www.google.com/"); 1479 const GURL kUrl1("http://www.google.com/");
1377 const GURL kUrl2("http://www.chromium.org/"); 1480 const GURL kUrl2("http://www.chromium.org/");
1378 1481
1379 // Navigate to the first page. 1482 // Navigate to the first page.
1380 contents()->NavigateAndCommit(kUrl1); 1483 contents()->NavigateAndCommit(kUrl1);
1381 TestRenderViewHost* rvh1 = test_rvh(); 1484 TestRenderViewHost* rvh1 = test_rvh();
1382 RenderViewHostDestructionObserver destruction_observer(rvh1); 1485 RenderViewHostDeletedObserver rvh_deleted_observer(rvh1);
1383 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state()); 1486 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
1384 1487
1385 // Navigate to new site, simulating onbeforeunload approval. 1488 // Navigate to new site, simulating onbeforeunload approval.
1386 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string()); 1489 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1387 base::TimeTicks now = base::TimeTicks::Now(); 1490 base::TimeTicks now = base::TimeTicks::Now();
1388 main_test_rfh()->OnMessageReceived( 1491 main_test_rfh()->OnMessageReceived(
1389 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); 1492 FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1390 EXPECT_TRUE(contents()->cross_navigation_pending()); 1493 EXPECT_TRUE(contents()->cross_navigation_pending());
1391 TestRenderViewHost* rvh2 = 1494 TestRenderViewHost* rvh2 =
1392 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost()); 1495 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
(...skipping 15 matching lines...) Expand all
1408 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state()); 1511 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state());
1409 1512
1410 // The new page commits. 1513 // The new page commits.
1411 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED); 1514 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1412 EXPECT_FALSE(contents()->cross_navigation_pending()); 1515 EXPECT_FALSE(contents()->cross_navigation_pending());
1413 EXPECT_EQ(rvh2, rvh()); 1516 EXPECT_EQ(rvh2, rvh());
1414 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL); 1517 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1415 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); 1518 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1416 1519
1417 // rvh1 should have been deleted. 1520 // rvh1 should have been deleted.
1418 EXPECT_TRUE(destruction_observer.rvh_deleted()); 1521 EXPECT_TRUE(rvh_deleted_observer.deleted());
1419 rvh1 = NULL; 1522 rvh1 = NULL;
1420 } 1523 }
1421 1524
1422 // Tests that the RenderViewHost is properly swapped out when the SwapOutACK is 1525 // Tests that the RenderViewHost is properly swapped out when the SwapOutACK is
1423 // received before the new page commits. 1526 // received before the new page commits.
1424 TEST_F(RenderFrameHostManagerTest, 1527 TEST_F(RenderFrameHostManagerTest,
1425 SwapOutACKBeforeNewPageCommitsLeadsToSwapOut) { 1528 SwapOutACKBeforeNewPageCommitsLeadsToSwapOut) {
1426 const GURL kUrl1("http://www.google.com/"); 1529 const GURL kUrl1("http://www.google.com/");
1427 const GURL kUrl2("http://www.chromium.org/"); 1530 const GURL kUrl2("http://www.chromium.org/");
1428 1531
1429 // Navigate to the first page. 1532 // Navigate to the first page.
1430 contents()->NavigateAndCommit(kUrl1); 1533 contents()->NavigateAndCommit(kUrl1);
1431 TestRenderViewHost* rvh1 = test_rvh(); 1534 TestRenderViewHost* rvh1 = test_rvh();
1432 RenderViewHostDestructionObserver destruction_observer(rvh1); 1535 RenderViewHostDeletedObserver rvh_deleted_observer(rvh1);
1433 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state()); 1536 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
1434 1537
1435 // Increment the number of active views in SiteInstanceImpl so that rvh2 is 1538 // Increment the number of active views in SiteInstanceImpl so that rvh2 is
1436 // not deleted on swap out. 1539 // not deleted on swap out.
1437 static_cast<SiteInstanceImpl*>( 1540 static_cast<SiteInstanceImpl*>(
1438 rvh1->GetSiteInstance())->increment_active_view_count(); 1541 rvh1->GetSiteInstance())->increment_active_view_count();
1439 1542
1440 // Navigate to new site, simulating onbeforeunload approval. 1543 // Navigate to new site, simulating onbeforeunload approval.
1441 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string()); 1544 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1442 base::TimeTicks now = base::TimeTicks::Now(); 1545 base::TimeTicks now = base::TimeTicks::Now();
(...skipping 20 matching lines...) Expand all
1463 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state()); 1566 EXPECT_EQ(RenderViewHostImpl::STATE_WAITING_FOR_COMMIT, rvh1->rvh_state());
1464 1567
1465 // The new page commits. 1568 // The new page commits.
1466 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED); 1569 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1467 EXPECT_FALSE(contents()->cross_navigation_pending()); 1570 EXPECT_FALSE(contents()->cross_navigation_pending());
1468 EXPECT_EQ(rvh2, rvh()); 1571 EXPECT_EQ(rvh2, rvh());
1469 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL); 1572 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1470 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); 1573 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1471 1574
1472 // rvh1 should be swapped out. 1575 // rvh1 should be swapped out.
1473 EXPECT_FALSE(destruction_observer.rvh_deleted()); 1576 EXPECT_FALSE(rvh_deleted_observer.deleted());
1474 EXPECT_TRUE(rvh1->IsSwappedOut()); 1577 EXPECT_TRUE(rvh1->IsSwappedOut());
1475 } 1578 }
1476 1579
1477 // Tests that the RenderViewHost is properly deleted when the new 1580 // Tests that the RenderViewHost is properly deleted when the new
1478 // page commits before the swap out ack is received. 1581 // page commits before the swap out ack is received.
1479 TEST_F(RenderFrameHostManagerTest, 1582 TEST_F(RenderFrameHostManagerTest,
1480 NewPageCommitsBeforeSwapOutACKLeadsToDeletion) { 1583 NewPageCommitsBeforeSwapOutACKLeadsToDeletion) {
1481 const GURL kUrl1("http://www.google.com/"); 1584 const GURL kUrl1("http://www.google.com/");
1482 const GURL kUrl2("http://www.chromium.org/"); 1585 const GURL kUrl2("http://www.chromium.org/");
1483 1586
1484 // Navigate to the first page. 1587 // Navigate to the first page.
1485 contents()->NavigateAndCommit(kUrl1); 1588 contents()->NavigateAndCommit(kUrl1);
1486 TestRenderViewHost* rvh1 = test_rvh(); 1589 TestRenderViewHost* rvh1 = test_rvh();
1487 RenderViewHostDestructionObserver destruction_observer(rvh1); 1590 RenderViewHostDeletedObserver rvh_deleted_observer(rvh1);
1488 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state()); 1591 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
1489 1592
1490 // Navigate to new site, simulating onbeforeunload approval. 1593 // Navigate to new site, simulating onbeforeunload approval.
1491 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string()); 1594 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1492 base::TimeTicks now = base::TimeTicks::Now(); 1595 base::TimeTicks now = base::TimeTicks::Now();
1493 main_test_rfh()->OnMessageReceived( 1596 main_test_rfh()->OnMessageReceived(
1494 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); 1597 FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1495 EXPECT_TRUE(contents()->cross_navigation_pending()); 1598 EXPECT_TRUE(contents()->cross_navigation_pending());
1496 TestRenderViewHost* rvh2 = 1599 TestRenderViewHost* rvh2 =
1497 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost()); 1600 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
(...skipping 15 matching lines...) Expand all
1513 EXPECT_FALSE(contents()->cross_navigation_pending()); 1616 EXPECT_FALSE(contents()->cross_navigation_pending());
1514 EXPECT_EQ(rvh2, rvh()); 1617 EXPECT_EQ(rvh2, rvh());
1515 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL); 1618 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1516 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); 1619 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1517 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN, rvh1->rvh_state()); 1620 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SHUTDOWN, rvh1->rvh_state());
1518 1621
1519 // Simulate the swap out ack. 1622 // Simulate the swap out ack.
1520 rvh1->OnSwappedOut(false); 1623 rvh1->OnSwappedOut(false);
1521 1624
1522 // rvh1 should have been deleted. 1625 // rvh1 should have been deleted.
1523 EXPECT_TRUE(destruction_observer.rvh_deleted()); 1626 EXPECT_TRUE(rvh_deleted_observer.deleted());
1524 rvh1 = NULL; 1627 rvh1 = NULL;
1525 } 1628 }
1526 1629
1527 // Tests that the RenderViewHost is properly swapped out when the new page 1630 // Tests that the RenderViewHost is properly swapped out when the new page
1528 // commits before the swap out ack is received. 1631 // commits before the swap out ack is received.
1529 TEST_F(RenderFrameHostManagerTest, 1632 TEST_F(RenderFrameHostManagerTest,
1530 NewPageCommitsBeforeSwapOutACKLeadsToSwapOut) { 1633 NewPageCommitsBeforeSwapOutACKLeadsToSwapOut) {
1531 const GURL kUrl1("http://www.google.com/"); 1634 const GURL kUrl1("http://www.google.com/");
1532 const GURL kUrl2("http://www.chromium.org/"); 1635 const GURL kUrl2("http://www.chromium.org/");
1533 1636
1534 // Navigate to the first page. 1637 // Navigate to the first page.
1535 contents()->NavigateAndCommit(kUrl1); 1638 contents()->NavigateAndCommit(kUrl1);
1536 TestRenderViewHost* rvh1 = test_rvh(); 1639 TestRenderViewHost* rvh1 = test_rvh();
1537 RenderViewHostDestructionObserver destruction_observer(rvh1); 1640 RenderViewHostDeletedObserver rvh_deleted_observer(rvh1);
1538 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state()); 1641 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
1539 1642
1540 // Increment the number of active views in SiteInstanceImpl so that rvh1 is 1643 // Increment the number of active views in SiteInstanceImpl so that rvh1 is
1541 // not deleted on swap out. 1644 // not deleted on swap out.
1542 static_cast<SiteInstanceImpl*>( 1645 static_cast<SiteInstanceImpl*>(
1543 rvh1->GetSiteInstance())->increment_active_view_count(); 1646 rvh1->GetSiteInstance())->increment_active_view_count();
1544 1647
1545 // Navigate to new site, simulating onbeforeunload approval. 1648 // Navigate to new site, simulating onbeforeunload approval.
1546 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string()); 1649 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1547 base::TimeTicks now = base::TimeTicks::Now(); 1650 base::TimeTicks now = base::TimeTicks::Now();
(...skipping 20 matching lines...) Expand all
1568 EXPECT_FALSE(contents()->cross_navigation_pending()); 1671 EXPECT_FALSE(contents()->cross_navigation_pending());
1569 EXPECT_EQ(rvh2, rvh()); 1672 EXPECT_EQ(rvh2, rvh());
1570 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL); 1673 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1571 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state()); 1674 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1572 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state()); 1675 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
1573 1676
1574 // Simulate the swap out ack. 1677 // Simulate the swap out ack.
1575 rvh1->OnSwappedOut(false); 1678 rvh1->OnSwappedOut(false);
1576 1679
1577 // rvh1 should be swapped out. 1680 // rvh1 should be swapped out.
1578 EXPECT_FALSE(destruction_observer.rvh_deleted()); 1681 EXPECT_FALSE(rvh_deleted_observer.deleted());
1579 EXPECT_TRUE(rvh1->IsSwappedOut()); 1682 EXPECT_TRUE(rvh1->IsSwappedOut());
1580 } 1683 }
1581 1684
1685 // Test that the RenderViewHost is properly swapped out if navigation in the
Charlie Reis 2014/03/24 23:24:43 a navigation
nasko 2014/03/25 18:30:22 Done.
1686 // new renderer commits before sendint the SwapOut message to the old renderer.
Charlie Reis 2014/03/24 23:24:43 sending
nasko 2014/03/25 18:30:22 Done.
1687 // This simulates a cross-site navigation to a synchronously committing URL
Charlie Reis 2014/03/24 23:24:43 a synchronously committing URL (e.g., a data URL)
nasko 2014/03/25 18:30:22 Done.
1688 // and ensures it works properly.
1689 TEST_F(RenderFrameHostManagerTest,
1690 CommitNewNavigationBeforeSendingSwapOut) {
1691 const GURL kUrl1("http://www.google.com/");
1692 const GURL kUrl2("http://www.chromium.org/");
1693
1694 // Navigate to the first page.
1695 contents()->NavigateAndCommit(kUrl1);
1696 TestRenderViewHost* rvh1 = test_rvh();
1697 RenderViewHostDeletedObserver rvh_deleted_observer(rvh1);
1698 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh1->rvh_state());
1699
1700 // Increment the number of active views in SiteInstanceImpl so that rvh1 is
1701 // not deleted on swap out.
1702 static_cast<SiteInstanceImpl*>(
1703 rvh1->GetSiteInstance())->increment_active_view_count();
1704
1705 // Navigate to new site, simulating onbeforeunload approval.
1706 controller().LoadURL(kUrl2, Referrer(), PAGE_TRANSITION_LINK, std::string());
1707 base::TimeTicks now = base::TimeTicks::Now();
1708 main_test_rfh()->OnMessageReceived(
1709 FrameHostMsg_BeforeUnload_ACK(0, true, now, now));
1710 EXPECT_TRUE(contents()->cross_navigation_pending());
1711 TestRenderViewHost* rvh2 =
1712 static_cast<TestRenderViewHost*>(contents()->GetPendingRenderViewHost());
1713
1714 // The new page commits.
1715 contents()->TestDidNavigate(rvh2, 1, kUrl2, PAGE_TRANSITION_TYPED);
1716 EXPECT_FALSE(contents()->cross_navigation_pending());
1717 EXPECT_EQ(rvh2, rvh());
1718 EXPECT_TRUE(contents()->GetPendingRenderViewHost() == NULL);
1719 EXPECT_EQ(RenderViewHostImpl::STATE_DEFAULT, rvh2->rvh_state());
1720 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT, rvh1->rvh_state());
1721
1722 // Simulate the effect of calling SwapOut in OnCrossSiteResponse.
Charlie Reis 2014/03/24 23:24:43 I thought we were testing the case without OnCross
nasko 2014/03/25 18:30:22 Done.
1723 rvh1->SwapOut();
1724 EXPECT_FALSE(contents()->cross_navigation_pending());
1725 EXPECT_EQ(RenderViewHostImpl::STATE_PENDING_SWAP_OUT,
1726 rvh1->rvh_state());
1727
1728 // Simulate the swap out ack.
1729 rvh1->OnSwappedOut(false);
1730
1731 // rvh1 should be swapped out.
1732 EXPECT_FALSE(rvh_deleted_observer.deleted());
1733 EXPECT_TRUE(rvh1->IsSwappedOut());
1734 }
1735
1582 } // namespace content 1736 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/frame_host/render_frame_host_manager.cc ('k') | content/browser/renderer_host/render_view_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698