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

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