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

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