OLD | NEW |
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/command_line.h" | 5 #include "base/command_line.h" |
6 #include "base/files/file_path.h" | 6 #include "base/files/file_path.h" |
7 #include "base/strings/utf_string_conversions.h" | 7 #include "base/strings/utf_string_conversions.h" |
8 #include "base/test/histogram_tester.h" | 8 #include "base/test/histogram_tester.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "content/browser/frame_host/cross_site_transferring_request.h" | 10 #include "content/browser/frame_host/cross_site_transferring_request.h" |
11 #include "content/browser/frame_host/navigation_controller_impl.h" | 11 #include "content/browser/frame_host/navigation_controller_impl.h" |
12 #include "content/browser/frame_host/navigation_entry_impl.h" | 12 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 13 #include "content/browser/frame_host/navigation_request.h" |
13 #include "content/browser/frame_host/navigator.h" | 14 #include "content/browser/frame_host/navigator.h" |
14 #include "content/browser/frame_host/render_frame_host_manager.h" | 15 #include "content/browser/frame_host/render_frame_host_manager.h" |
15 #include "content/browser/frame_host/render_frame_proxy_host.h" | 16 #include "content/browser/frame_host/render_frame_proxy_host.h" |
16 #include "content/browser/site_instance_impl.h" | 17 #include "content/browser/site_instance_impl.h" |
17 #include "content/browser/webui/web_ui_controller_factory_registry.h" | 18 #include "content/browser/webui/web_ui_controller_factory_registry.h" |
18 #include "content/common/frame_messages.h" | 19 #include "content/common/frame_messages.h" |
19 #include "content/common/view_messages.h" | 20 #include "content/common/view_messages.h" |
20 #include "content/public/browser/notification_details.h" | 21 #include "content/public/browser/notification_details.h" |
21 #include "content/public/browser/notification_service.h" | 22 #include "content/public/browser/notification_service.h" |
22 #include "content/public/browser/notification_source.h" | 23 #include "content/public/browser/notification_source.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 void set_should_create_webui(bool should_create_webui) { | 255 void set_should_create_webui(bool should_create_webui) { |
255 factory_.set_should_create_webui(should_create_webui); | 256 factory_.set_should_create_webui(should_create_webui); |
256 } | 257 } |
257 | 258 |
258 void NavigateActiveAndCommit(const GURL& url) { | 259 void NavigateActiveAndCommit(const GURL& url) { |
259 // Note: we navigate the active RenderFrameHost because previous navigations | 260 // Note: we navigate the active RenderFrameHost because previous navigations |
260 // won't have committed yet, so NavigateAndCommit does the wrong thing | 261 // won't have committed yet, so NavigateAndCommit does the wrong thing |
261 // for us. | 262 // for us. |
262 controller().LoadURL( | 263 controller().LoadURL( |
263 url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 264 url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| 265 |
| 266 // Simulate the BeforeUnload_ACK that is received from the current renderer |
| 267 // for a cross-site navigation. |
| 268 // PlzNavigate: it is necessary to call PrepareForCommit before getting the |
| 269 // main and the pending frame because when we are trying to navigate to a |
| 270 // WebUI from a new tab, a RenderFrameHost is created to display it that is |
| 271 // committed immediately (since it is a new tab). Therefore the main frame |
| 272 // is replaced without a pending frame being created, and we don't get the |
| 273 // right values for the RFH to navigate: we try to use the old one that has |
| 274 // been deleted in the meantime. |
| 275 contents()->GetMainFrame()->PrepareForCommit(url); |
| 276 |
264 TestRenderFrameHost* old_rfh = contents()->GetMainFrame(); | 277 TestRenderFrameHost* old_rfh = contents()->GetMainFrame(); |
265 TestRenderFrameHost* active_rfh = contents()->GetPendingMainFrame() | 278 TestRenderFrameHost* active_rfh = contents()->GetPendingMainFrame() |
266 ? contents()->GetPendingMainFrame() | 279 ? contents()->GetPendingMainFrame() |
267 : old_rfh; | 280 : old_rfh; |
268 | 281 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, old_rfh->rfh_state()); |
269 // Simulate the BeforeUnload_ACK that is received from the current renderer | |
270 // for a cross-site navigation. | |
271 if (old_rfh != active_rfh) { | |
272 old_rfh->SendBeforeUnloadACK(true); | |
273 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, old_rfh->rfh_state()); | |
274 } | |
275 | 282 |
276 // Commit the navigation with a new page ID. | 283 // Commit the navigation with a new page ID. |
277 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance( | 284 int32 max_page_id = contents()->GetMaxPageIDForSiteInstance( |
278 active_rfh->GetSiteInstance()); | 285 active_rfh->GetSiteInstance()); |
279 | 286 |
280 // Use an observer to avoid accessing a deleted renderer later on when the | 287 // Use an observer to avoid accessing a deleted renderer later on when the |
281 // state is being checked. | 288 // state is being checked. |
282 RenderFrameHostDeletedObserver rfh_observer(old_rfh); | 289 RenderFrameHostDeletedObserver rfh_observer(old_rfh); |
283 RenderViewHostDeletedObserver rvh_observer(old_rfh->GetRenderViewHost()); | 290 RenderViewHostDeletedObserver rvh_observer(old_rfh->GetRenderViewHost()); |
284 active_rfh->SendNavigate(max_page_id + 1, url); | 291 active_rfh->SendNavigate(max_page_id + 1, url); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 const GURL kChromeURL("chrome://foo"); | 344 const GURL kChromeURL("chrome://foo"); |
338 const GURL kDestUrl("http://www.google.com/"); | 345 const GURL kDestUrl("http://www.google.com/"); |
339 | 346 |
340 // Navigate our first tab to a chrome url and then to the destination. | 347 // Navigate our first tab to a chrome url and then to the destination. |
341 NavigateActiveAndCommit(kChromeURL); | 348 NavigateActiveAndCommit(kChromeURL); |
342 TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame(); | 349 TestRenderFrameHost* ntp_rfh = contents()->GetMainFrame(); |
343 | 350 |
344 // Navigate to a cross-site URL. | 351 // Navigate to a cross-site URL. |
345 contents()->GetController().LoadURL( | 352 contents()->GetController().LoadURL( |
346 kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 353 kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| 354 contents()->GetMainFrame()->PrepareForCommit(kDestUrl); |
347 EXPECT_TRUE(contents()->cross_navigation_pending()); | 355 EXPECT_TRUE(contents()->cross_navigation_pending()); |
348 | 356 |
349 // Manually increase the number of active frames in the | 357 // Manually increase the number of active frames in the |
350 // SiteInstance that ntp_rfh belongs to, to prevent it from being | 358 // SiteInstance that ntp_rfh belongs to, to prevent it from being |
351 // destroyed when it gets swapped out. | 359 // destroyed when it gets swapped out. |
352 ntp_rfh->GetSiteInstance()->increment_active_frame_count(); | 360 ntp_rfh->GetSiteInstance()->increment_active_frame_count(); |
353 | 361 |
354 TestRenderFrameHost* dest_rfh = contents()->GetPendingMainFrame(); | 362 TestRenderFrameHost* dest_rfh = contents()->GetPendingMainFrame(); |
355 CHECK(dest_rfh); | 363 CHECK(dest_rfh); |
356 EXPECT_NE(ntp_rfh, dest_rfh); | 364 EXPECT_NE(ntp_rfh, dest_rfh); |
357 | 365 |
358 // BeforeUnload finishes. | 366 // BeforeUnload finishes. |
359 ntp_rfh->SendBeforeUnloadACK(true); | 367 ntp_rfh->SendBeforeUnloadACK(true); |
360 | 368 |
361 dest_rfh->SendNavigate(101, kDestUrl); | 369 dest_rfh->SendNavigate(101, kDestUrl); |
362 ntp_rfh->OnSwappedOut(); | 370 ntp_rfh->OnSwappedOut(); |
363 | 371 |
364 EXPECT_TRUE(ntp_rfh->is_swapped_out()); | 372 EXPECT_TRUE(ntp_rfh->is_swapped_out()); |
365 return ntp_rfh; | 373 return ntp_rfh; |
366 } | 374 } |
367 | 375 |
| 376 // Returns the RenderFrameHost that should be used in the navigation to |
| 377 // |entry|. |
| 378 RenderFrameHostImpl* GetFrameHostForNavigation( |
| 379 RenderFrameHostManager* manager, |
| 380 const NavigationEntryImpl& entry) { |
| 381 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 382 switches::kEnableBrowserSideNavigation)) { |
| 383 scoped_ptr<NavigationRequest> navigation_request = |
| 384 NavigationRequest::Create(manager->frame_tree_node_, entry, |
| 385 FrameMsg_Navigate_Type::NORMAL, |
| 386 base::TimeTicks::Now()); |
| 387 return manager->GetFrameHostForNavigation(*navigation_request); |
| 388 } |
| 389 return manager->Navigate(entry); |
| 390 } |
| 391 |
| 392 // Returns the pending RenderFrameHost. |
| 393 // PlzNavigate: returns the speculative RenderFrameHost. |
| 394 RenderFrameHostImpl* GetPendingFrameHost( |
| 395 RenderFrameHostManager* manager) { |
| 396 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 397 switches::kEnableBrowserSideNavigation)) { |
| 398 return manager->speculative_render_frame_host_.get(); |
| 399 } |
| 400 return manager->pending_frame_host(); |
| 401 } |
| 402 |
368 private: | 403 private: |
369 RenderFrameHostManagerTestWebUIControllerFactory factory_; | 404 RenderFrameHostManagerTestWebUIControllerFactory factory_; |
370 }; | 405 }; |
371 | 406 |
372 // Tests that when you navigate from a chrome:// url to another page, and | 407 // Tests that when you navigate from a chrome:// url to another page, and |
373 // then do that same thing in another tab, that the two resulting pages have | 408 // then do that same thing in another tab, that the two resulting pages have |
374 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is | 409 // different SiteInstances, BrowsingInstances, and RenderProcessHosts. This is |
375 // a regression test for bug 9364. | 410 // a regression test for bug 9364. |
376 TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) { | 411 TEST_F(RenderFrameHostManagerTest, NewTabPageProcesses) { |
377 set_should_create_webui(true); | 412 set_should_create_webui(true); |
(...skipping 10 matching lines...) Expand all Loading... |
388 | 423 |
389 // Make a second tab. | 424 // Make a second tab. |
390 scoped_ptr<TestWebContents> contents2( | 425 scoped_ptr<TestWebContents> contents2( |
391 TestWebContents::Create(browser_context(), NULL)); | 426 TestWebContents::Create(browser_context(), NULL)); |
392 | 427 |
393 // Load the two URLs in the second tab. Note that the first navigation creates | 428 // Load the two URLs in the second tab. Note that the first navigation creates |
394 // a RFH that's not pending (since there is no cross-site transition), so | 429 // a RFH that's not pending (since there is no cross-site transition), so |
395 // we use the committed one. | 430 // we use the committed one. |
396 contents2->GetController().LoadURL( | 431 contents2->GetController().LoadURL( |
397 kChromeUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 432 kChromeUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| 433 contents2->GetMainFrame()->PrepareForCommit(kChromeUrl); |
398 TestRenderFrameHost* ntp_rfh2 = contents2->GetMainFrame(); | 434 TestRenderFrameHost* ntp_rfh2 = contents2->GetMainFrame(); |
399 EXPECT_FALSE(contents2->cross_navigation_pending()); | 435 EXPECT_FALSE(contents2->cross_navigation_pending()); |
400 ntp_rfh2->SendNavigate(100, kChromeUrl); | 436 ntp_rfh2->SendNavigate(100, kChromeUrl); |
401 | 437 |
402 // The second one is the opposite, creating a cross-site transition and | 438 // The second one is the opposite, creating a cross-site transition and |
403 // requiring a beforeunload ack. | 439 // requiring a beforeunload ack. |
404 contents2->GetController().LoadURL( | 440 contents2->GetController().LoadURL( |
405 kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 441 kDestUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| 442 contents2->GetMainFrame()->PrepareForCommit(kDestUrl); |
406 EXPECT_TRUE(contents2->cross_navigation_pending()); | 443 EXPECT_TRUE(contents2->cross_navigation_pending()); |
407 TestRenderFrameHost* dest_rfh2 = contents2->GetPendingMainFrame(); | 444 TestRenderFrameHost* dest_rfh2 = contents2->GetPendingMainFrame(); |
408 ASSERT_TRUE(dest_rfh2); | 445 ASSERT_TRUE(dest_rfh2); |
409 | 446 |
410 ntp_rfh2->SendBeforeUnloadACK(true); | |
411 dest_rfh2->SendNavigate(101, kDestUrl); | 447 dest_rfh2->SendNavigate(101, kDestUrl); |
412 | 448 |
413 // The two RFH's should be different in every way. | 449 // The two RFH's should be different in every way. |
414 EXPECT_NE(contents()->GetMainFrame()->GetProcess(), dest_rfh2->GetProcess()); | 450 EXPECT_NE(contents()->GetMainFrame()->GetProcess(), dest_rfh2->GetProcess()); |
415 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(), | 451 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(), |
416 dest_rfh2->GetSiteInstance()); | 452 dest_rfh2->GetSiteInstance()); |
417 EXPECT_FALSE(dest_rfh2->GetSiteInstance()->IsRelatedSiteInstance( | 453 EXPECT_FALSE(dest_rfh2->GetSiteInstance()->IsRelatedSiteInstance( |
418 contents()->GetMainFrame()->GetSiteInstance())); | 454 contents()->GetMainFrame()->GetSiteInstance())); |
419 | 455 |
420 // Navigate both to the new tab page, and verify that they share a | 456 // Navigate both to the new tab page, and verify that they share a |
421 // RenderProcessHost (not a SiteInstance). | 457 // RenderProcessHost (not a SiteInstance). |
422 NavigateActiveAndCommit(kChromeUrl); | 458 NavigateActiveAndCommit(kChromeUrl); |
423 EXPECT_FALSE(contents()->GetPendingMainFrame()); | 459 EXPECT_FALSE(contents()->GetPendingMainFrame()); |
424 | 460 |
425 contents2->GetController().LoadURL( | 461 contents2->GetController().LoadURL( |
426 kChromeUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 462 kChromeUrl, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
427 dest_rfh2->SendBeforeUnloadACK(true); | 463 contents2->GetMainFrame()->PrepareForCommit(kChromeUrl); |
428 contents2->GetPendingMainFrame()->SendNavigate(102, kChromeUrl); | 464 contents2->GetPendingMainFrame()->SendNavigate(102, kChromeUrl); |
429 | 465 |
430 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(), | 466 EXPECT_NE(contents()->GetMainFrame()->GetSiteInstance(), |
431 contents2->GetMainFrame()->GetSiteInstance()); | 467 contents2->GetMainFrame()->GetSiteInstance()); |
432 EXPECT_EQ(contents()->GetMainFrame()->GetSiteInstance()->GetProcess(), | 468 EXPECT_EQ(contents()->GetMainFrame()->GetSiteInstance()->GetProcess(), |
433 contents2->GetMainFrame()->GetSiteInstance()->GetProcess()); | 469 contents2->GetMainFrame()->GetSiteInstance()->GetProcess()); |
434 } | 470 } |
435 | 471 |
436 // Ensure that the browser ignores most IPC messages that arrive from a | 472 // Ensure that the browser ignores most IPC messages that arrive from a |
437 // RenderViewHost that has been swapped out. We do not want to take | 473 // RenderViewHost that has been swapped out. We do not want to take |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 // one will create a new SiteInstance. Because current_instance and | 788 // one will create a new SiteInstance. Because current_instance and |
753 // new_instance will be different, a new RenderViewHost will be created for | 789 // new_instance will be different, a new RenderViewHost will be created for |
754 // the second navigation. We have to avoid this in order to exercise the | 790 // the second navigation. We have to avoid this in order to exercise the |
755 // target code patch. | 791 // target code patch. |
756 NavigateActiveAndCommit(kChromeUrl); | 792 NavigateActiveAndCommit(kChromeUrl); |
757 | 793 |
758 // Navigate. | 794 // Navigate. |
759 controller().LoadURL( | 795 controller().LoadURL( |
760 kUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); | 796 kUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); |
761 // Simulate response from RenderFrame for DispatchBeforeUnload. | 797 // Simulate response from RenderFrame for DispatchBeforeUnload. |
762 base::TimeTicks now = base::TimeTicks::Now(); | 798 contents()->GetMainFrame()->PrepareForCommit(kUrl); |
763 contents()->GetMainFrame()->OnMessageReceived(FrameHostMsg_BeforeUnload_ACK( | |
764 contents()->GetMainFrame()->GetRoutingID(), true, now, now)); | |
765 ASSERT_TRUE(contents()->GetPendingMainFrame()) | 799 ASSERT_TRUE(contents()->GetPendingMainFrame()) |
766 << "Expected new pending RenderFrameHost to be created."; | 800 << "Expected new pending RenderFrameHost to be created."; |
767 RenderFrameHost* last_rfh = contents()->GetPendingMainFrame(); | 801 RenderFrameHost* last_rfh = contents()->GetPendingMainFrame(); |
768 int32 new_id = | 802 int32 new_id = |
769 contents()->GetMaxPageIDForSiteInstance(last_rfh->GetSiteInstance()) + 1; | 803 contents()->GetMaxPageIDForSiteInstance(last_rfh->GetSiteInstance()) + 1; |
770 contents()->GetPendingMainFrame()->SendNavigate(new_id, kUrl); | 804 contents()->GetPendingMainFrame()->SendNavigate(new_id, kUrl); |
771 EXPECT_EQ(controller().GetLastCommittedEntryIndex(), 1); | 805 EXPECT_EQ(controller().GetLastCommittedEntryIndex(), 1); |
772 ASSERT_TRUE(controller().GetLastCommittedEntry()); | 806 ASSERT_TRUE(controller().GetLastCommittedEntry()); |
773 EXPECT_TRUE(kUrl == controller().GetLastCommittedEntry()->GetURL()); | 807 EXPECT_TRUE(kUrl == controller().GetLastCommittedEntry()->GetURL()); |
774 EXPECT_FALSE(controller().GetPendingEntry()); | 808 EXPECT_FALSE(controller().GetPendingEntry()); |
775 // Because we're using TestWebContents and TestRenderViewHost in this | 809 // Because we're using TestWebContents and TestRenderViewHost in this |
776 // unittest, no one calls WebContentsImpl::RenderViewCreated(). So, we see no | 810 // unittest, no one calls WebContentsImpl::RenderViewCreated(). So, we see no |
777 // EnableViewSourceMode message, here. | 811 // EnableViewSourceMode message, here. |
778 | 812 |
779 // Clear queued messages before load. | 813 // Clear queued messages before load. |
780 process()->sink().ClearMessages(); | 814 process()->sink().ClearMessages(); |
781 // Navigate, again. | 815 // Navigate, again. |
782 controller().LoadURL( | 816 controller().LoadURL( |
783 kUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); | 817 kUrl, Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); |
| 818 contents()->GetMainFrame()->PrepareForCommit(kUrl); |
784 // The same RenderViewHost should be reused. | 819 // The same RenderViewHost should be reused. |
785 EXPECT_FALSE(contents()->GetPendingMainFrame()); | 820 EXPECT_FALSE(contents()->GetPendingMainFrame()); |
786 EXPECT_TRUE(last_rfh == contents()->GetMainFrame()); | 821 EXPECT_TRUE(last_rfh == contents()->GetMainFrame()); |
787 // Navigate using the returned page_id. | 822 // Navigate using the returned page_id. |
788 contents()->GetMainFrame()->SendNavigate(new_id, kUrl); | 823 contents()->GetMainFrame()->SendNavigate(new_id, kUrl); |
789 EXPECT_EQ(controller().GetLastCommittedEntryIndex(), 1); | 824 EXPECT_EQ(controller().GetLastCommittedEntryIndex(), 1); |
790 EXPECT_FALSE(controller().GetPendingEntry()); | 825 EXPECT_FALSE(controller().GetPendingEntry()); |
791 // New message should be sent out to make sure to enter view-source mode. | 826 // New message should be sent out to make sure to enter view-source mode. |
792 EXPECT_TRUE(process()->sink().GetUniqueMessageMatching( | 827 EXPECT_TRUE(process()->sink().GetUniqueMessageMatching( |
793 ViewMsg_EnableViewSourceMode::ID)); | 828 ViewMsg_EnableViewSourceMode::ID)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 | 865 |
831 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); | 866 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); |
832 RenderFrameHostImpl* host = NULL; | 867 RenderFrameHostImpl* host = NULL; |
833 | 868 |
834 // 1) The first navigation. -------------------------- | 869 // 1) The first navigation. -------------------------- |
835 const GURL kUrl1("http://www.google.com/"); | 870 const GURL kUrl1("http://www.google.com/"); |
836 NavigationEntryImpl entry1( | 871 NavigationEntryImpl entry1( |
837 NULL /* instance */, -1 /* page_id */, kUrl1, Referrer(), | 872 NULL /* instance */, -1 /* page_id */, kUrl1, Referrer(), |
838 base::string16() /* title */, ui::PAGE_TRANSITION_TYPED, | 873 base::string16() /* title */, ui::PAGE_TRANSITION_TYPED, |
839 false /* is_renderer_init */); | 874 false /* is_renderer_init */); |
840 host = manager->Navigate(entry1); | 875 host = GetFrameHostForNavigation(manager, entry1); |
841 | 876 |
842 // The RenderFrameHost created in Init will be reused. | 877 // The RenderFrameHost created in Init will be reused. |
843 EXPECT_TRUE(host == manager->current_frame_host()); | 878 EXPECT_TRUE(host == manager->current_frame_host()); |
844 EXPECT_FALSE(manager->pending_frame_host()); | 879 EXPECT_FALSE(GetPendingFrameHost(manager)); |
845 | 880 |
846 // Commit. | 881 // Commit. |
847 manager->DidNavigateFrame(host, true); | 882 manager->DidNavigateFrame(host, true); |
848 // Commit to SiteInstance should be delayed until RenderFrame commit. | 883 // Commit to SiteInstance should be delayed until RenderFrame commit. |
849 EXPECT_TRUE(host == manager->current_frame_host()); | 884 EXPECT_TRUE(host == manager->current_frame_host()); |
850 ASSERT_TRUE(host); | 885 ASSERT_TRUE(host); |
851 EXPECT_FALSE(host->GetSiteInstance()->HasSite()); | 886 EXPECT_FALSE(host->GetSiteInstance()->HasSite()); |
852 host->GetSiteInstance()->SetSite(kUrl1); | 887 host->GetSiteInstance()->SetSite(kUrl1); |
853 | 888 |
854 // 2) Navigate to next site. ------------------------- | 889 // 2) Navigate to next site. ------------------------- |
855 const GURL kUrl2("http://www.google.com/foo"); | 890 const GURL kUrl2("http://www.google.com/foo"); |
856 NavigationEntryImpl entry2( | 891 NavigationEntryImpl entry2( |
857 NULL /* instance */, -1 /* page_id */, kUrl2, | 892 NULL /* instance */, -1 /* page_id */, kUrl2, |
858 Referrer(kUrl1, blink::WebReferrerPolicyDefault), | 893 Referrer(kUrl1, blink::WebReferrerPolicyDefault), |
859 base::string16() /* title */, ui::PAGE_TRANSITION_LINK, | 894 base::string16() /* title */, ui::PAGE_TRANSITION_LINK, |
860 true /* is_renderer_init */); | 895 true /* is_renderer_init */); |
861 host = manager->Navigate(entry2); | 896 host = GetFrameHostForNavigation(manager, entry2); |
862 | 897 |
863 // The RenderFrameHost created in Init will be reused. | 898 // The RenderFrameHost created in Init will be reused. |
864 EXPECT_TRUE(host == manager->current_frame_host()); | 899 EXPECT_TRUE(host == manager->current_frame_host()); |
865 EXPECT_FALSE(manager->pending_frame_host()); | 900 EXPECT_FALSE(GetPendingFrameHost(manager)); |
866 | 901 |
867 // Commit. | 902 // Commit. |
868 manager->DidNavigateFrame(host, true); | 903 manager->DidNavigateFrame(host, true); |
869 EXPECT_TRUE(host == manager->current_frame_host()); | 904 EXPECT_TRUE(host == manager->current_frame_host()); |
870 ASSERT_TRUE(host); | 905 ASSERT_TRUE(host); |
871 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); | 906 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); |
872 | 907 |
873 // 3) Cross-site navigate to next site. -------------- | 908 // 3) Cross-site navigate to next site. -------------- |
874 const GURL kUrl3("http://webkit.org/"); | 909 const GURL kUrl3("http://webkit.org/"); |
875 NavigationEntryImpl entry3( | 910 NavigationEntryImpl entry3( |
876 NULL /* instance */, -1 /* page_id */, kUrl3, | 911 NULL /* instance */, -1 /* page_id */, kUrl3, |
877 Referrer(kUrl2, blink::WebReferrerPolicyDefault), | 912 Referrer(kUrl2, blink::WebReferrerPolicyDefault), |
878 base::string16() /* title */, ui::PAGE_TRANSITION_LINK, | 913 base::string16() /* title */, ui::PAGE_TRANSITION_LINK, |
879 false /* is_renderer_init */); | 914 false /* is_renderer_init */); |
880 host = manager->Navigate(entry3); | 915 host = GetFrameHostForNavigation(manager, entry3); |
881 | 916 |
882 // A new RenderFrameHost should be created. | 917 // A new RenderFrameHost should be created. |
883 EXPECT_TRUE(manager->pending_frame_host()); | 918 EXPECT_TRUE(GetPendingFrameHost(manager)); |
884 ASSERT_EQ(host, manager->pending_frame_host()); | 919 ASSERT_EQ(host, GetPendingFrameHost(manager)); |
885 | 920 |
886 notifications.Reset(); | 921 notifications.Reset(); |
887 | 922 |
888 // Commit. | 923 // Commit. |
889 manager->DidNavigateFrame(manager->pending_frame_host(), true); | 924 manager->DidNavigateFrame(GetPendingFrameHost(manager), true); |
890 EXPECT_TRUE(host == manager->current_frame_host()); | 925 EXPECT_TRUE(host == manager->current_frame_host()); |
891 ASSERT_TRUE(host); | 926 ASSERT_TRUE(host); |
892 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); | 927 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); |
893 // Check the pending RenderFrameHost has been committed. | 928 // Check the pending RenderFrameHost has been committed. |
894 EXPECT_FALSE(manager->pending_frame_host()); | 929 EXPECT_FALSE(GetPendingFrameHost(manager)); |
895 | 930 |
896 // We should observe a notification. | 931 // We should observe a notification. |
897 EXPECT_TRUE( | 932 EXPECT_TRUE( |
898 notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); | 933 notifications.Check1AndReset(NOTIFICATION_RENDER_VIEW_HOST_CHANGED)); |
899 } | 934 } |
900 | 935 |
901 // Tests WebUI creation. | 936 // Tests WebUI creation. |
902 TEST_F(RenderFrameHostManagerTest, WebUI) { | 937 TEST_F(RenderFrameHostManagerTest, WebUI) { |
903 set_should_create_webui(true); | 938 set_should_create_webui(true); |
904 SiteInstance* instance = SiteInstance::Create(browser_context()); | 939 SiteInstance* instance = SiteInstance::Create(browser_context()); |
905 | 940 |
906 scoped_ptr<TestWebContents> web_contents( | 941 scoped_ptr<TestWebContents> web_contents( |
907 TestWebContents::Create(browser_context(), instance)); | 942 TestWebContents::Create(browser_context(), instance)); |
908 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); | 943 RenderFrameHostManager* manager = web_contents->GetRenderManagerForTesting(); |
909 | 944 |
910 EXPECT_FALSE(manager->current_host()->IsRenderViewLive()); | 945 EXPECT_FALSE(manager->current_host()->IsRenderViewLive()); |
911 | 946 |
912 const GURL kUrl("chrome://foo"); | 947 const GURL kUrl("chrome://foo"); |
913 NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, | 948 NavigationEntryImpl entry(NULL /* instance */, -1 /* page_id */, kUrl, |
914 Referrer(), base::string16() /* title */, | 949 Referrer(), base::string16() /* title */, |
915 ui::PAGE_TRANSITION_TYPED, | 950 ui::PAGE_TRANSITION_TYPED, |
916 false /* is_renderer_init */); | 951 false /* is_renderer_init */); |
917 RenderFrameHostImpl* host = manager->Navigate(entry); | 952 RenderFrameHostImpl* host = GetFrameHostForNavigation(manager, entry); |
918 | 953 |
919 // We commit the pending RenderFrameHost immediately because the previous | 954 // We commit the pending RenderFrameHost immediately because the previous |
920 // RenderFrameHost was not live. We test a case where it is live in | 955 // RenderFrameHost was not live. We test a case where it is live in |
921 // WebUIInNewTab. | 956 // WebUIInNewTab. |
922 EXPECT_TRUE(host); | 957 EXPECT_TRUE(host); |
923 EXPECT_EQ(host, manager->current_frame_host()); | 958 EXPECT_EQ(host, manager->current_frame_host()); |
924 EXPECT_FALSE(manager->pending_frame_host()); | 959 EXPECT_FALSE(GetPendingFrameHost(manager)); |
925 | 960 |
926 // It's important that the site instance get set on the Web UI page as soon | 961 // It's important that the site instance get set on the Web UI page as soon |
927 // as the navigation starts, rather than lazily after it commits, so we don't | 962 // as the navigation starts, rather than lazily after it commits, so we don't |
928 // try to re-use the SiteInstance/process for non Web UI things that may | 963 // try to re-use the SiteInstance/process for non Web UI things that may |
929 // get loaded in between. | 964 // get loaded in between. |
930 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); | 965 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); |
931 EXPECT_EQ(kUrl, host->GetSiteInstance()->GetSiteURL()); | 966 EXPECT_EQ(kUrl, host->GetSiteInstance()->GetSiteURL()); |
932 | 967 |
933 // The Web UI is committed immediately because the RenderViewHost has not been | 968 // The Web UI is committed immediately because the RenderViewHost has not been |
934 // used yet. UpdateStateForNavigate() took the short cut path. | 969 // used yet. UpdateStateForNavigate() took the short cut path. |
(...skipping 22 matching lines...) Expand all Loading... |
957 base::string16(), -1, MSG_ROUTING_NONE, -1, false); | 992 base::string16(), -1, MSG_ROUTING_NONE, -1, false); |
958 EXPECT_TRUE(manager1->current_host()->IsRenderViewLive()); | 993 EXPECT_TRUE(manager1->current_host()->IsRenderViewLive()); |
959 EXPECT_TRUE(manager1->current_frame_host()->IsRenderFrameLive()); | 994 EXPECT_TRUE(manager1->current_frame_host()->IsRenderFrameLive()); |
960 | 995 |
961 // Navigate to a WebUI page. | 996 // Navigate to a WebUI page. |
962 const GURL kUrl1("chrome://foo"); | 997 const GURL kUrl1("chrome://foo"); |
963 NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1, | 998 NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1, |
964 Referrer(), base::string16() /* title */, | 999 Referrer(), base::string16() /* title */, |
965 ui::PAGE_TRANSITION_TYPED, | 1000 ui::PAGE_TRANSITION_TYPED, |
966 false /* is_renderer_init */); | 1001 false /* is_renderer_init */); |
967 RenderFrameHostImpl* host1 = manager1->Navigate(entry1); | 1002 RenderFrameHostImpl* host1 = GetFrameHostForNavigation(manager1, entry1); |
968 | 1003 |
969 // We should have a pending navigation to the WebUI RenderViewHost. | 1004 // We should have a pending navigation to the WebUI RenderViewHost. |
970 // It should already have bindings. | 1005 // It should already have bindings. |
971 EXPECT_EQ(host1, manager1->pending_frame_host()); | 1006 EXPECT_EQ(host1, GetPendingFrameHost(manager1)); |
972 EXPECT_NE(host1, manager1->current_frame_host()); | 1007 EXPECT_NE(host1, manager1->current_frame_host()); |
973 EXPECT_TRUE( | 1008 EXPECT_TRUE( |
974 host1->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); | 1009 host1->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); |
975 | 1010 |
976 // Commit and ensure we still have bindings. | 1011 // Commit and ensure we still have bindings. |
977 manager1->DidNavigateFrame(host1, true); | 1012 manager1->DidNavigateFrame(host1, true); |
978 SiteInstance* webui_instance = host1->GetSiteInstance(); | 1013 SiteInstance* webui_instance = host1->GetSiteInstance(); |
979 EXPECT_EQ(host1, manager1->current_frame_host()); | 1014 EXPECT_EQ(host1, manager1->current_frame_host()); |
980 EXPECT_TRUE( | 1015 EXPECT_TRUE( |
981 host1->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); | 1016 host1->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); |
982 | 1017 |
983 // Now simulate clicking a link that opens in a new tab. | 1018 // Now simulate clicking a link that opens in a new tab. |
984 scoped_ptr<TestWebContents> web_contents2( | 1019 scoped_ptr<TestWebContents> web_contents2( |
985 TestWebContents::Create(browser_context(), webui_instance)); | 1020 TestWebContents::Create(browser_context(), webui_instance)); |
986 RenderFrameHostManager* manager2 = | 1021 RenderFrameHostManager* manager2 = |
987 web_contents2->GetRenderManagerForTesting(); | 1022 web_contents2->GetRenderManagerForTesting(); |
988 // Make sure the new RVH is considered live. This is usually done in | 1023 // Make sure the new RVH is considered live. This is usually done in |
989 // RenderWidgetHost::Init when opening a new tab from a link. | 1024 // RenderWidgetHost::Init when opening a new tab from a link. |
990 manager2->current_host()->CreateRenderView( | 1025 manager2->current_host()->CreateRenderView( |
991 base::string16(), -1, MSG_ROUTING_NONE, -1, false); | 1026 base::string16(), -1, MSG_ROUTING_NONE, -1, false); |
992 | 1027 |
993 const GURL kUrl2("chrome://foo/bar"); | 1028 const GURL kUrl2("chrome://foo/bar"); |
994 NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, | 1029 NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, |
995 Referrer(), base::string16() /* title */, | 1030 Referrer(), base::string16() /* title */, |
996 ui::PAGE_TRANSITION_LINK, | 1031 ui::PAGE_TRANSITION_LINK, |
997 true /* is_renderer_init */); | 1032 true /* is_renderer_init */); |
998 RenderFrameHostImpl* host2 = manager2->Navigate(entry2); | 1033 RenderFrameHostImpl* host2 = GetFrameHostForNavigation(manager2, entry2); |
999 | 1034 |
1000 // No cross-process transition happens because we are already in the right | 1035 // No cross-process transition happens because we are already in the right |
1001 // SiteInstance. We should grant bindings immediately. | 1036 // SiteInstance. We should grant bindings immediately. |
1002 EXPECT_EQ(host2, manager2->current_frame_host()); | 1037 EXPECT_EQ(host2, manager2->current_frame_host()); |
1003 EXPECT_TRUE( | 1038 EXPECT_TRUE( |
1004 host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); | 1039 host2->render_view_host()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI); |
1005 | 1040 |
1006 manager2->DidNavigateFrame(host2, true); | 1041 manager2->DidNavigateFrame(host2, true); |
1007 } | 1042 } |
1008 | 1043 |
1009 // Tests that we don't end up in an inconsistent state if a page does a back and | 1044 // Tests that we don't end up in an inconsistent state if a page does a back and |
1010 // then reload. http://crbug.com/51680 | 1045 // then reload. http://crbug.com/51680 |
1011 // Also tests that only user-gesture navigations can interrupt cross-process | 1046 // Also tests that only user-gesture navigations can interrupt cross-process |
1012 // navigations. http://crbug.com/75195 | 1047 // navigations. http://crbug.com/75195 |
1013 TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) { | 1048 TEST_F(RenderFrameHostManagerTest, PageDoesBackAndReload) { |
1014 const GURL kUrl1("http://www.google.com/"); | 1049 const GURL kUrl1("http://www.google.com/"); |
1015 const GURL kUrl2("http://www.evil-site.com/"); | 1050 const GURL kUrl2("http://www.evil-site.com/"); |
1016 | 1051 |
1017 // Navigate to a safe site, then an evil site. | 1052 // Navigate to a safe site, then an evil site. |
1018 // This will switch RenderFrameHosts. We cannot assert that the first and | 1053 // This will switch RenderFrameHosts. We cannot assert that the first and |
1019 // second RFHs are different, though, because the first one may be promptly | 1054 // second RFHs are different, though, because the first one may be promptly |
1020 // deleted. | 1055 // deleted. |
1021 contents()->NavigateAndCommit(kUrl1); | 1056 contents()->NavigateAndCommit(kUrl1); |
1022 contents()->NavigateAndCommit(kUrl2); | 1057 contents()->NavigateAndCommit(kUrl2); |
1023 TestRenderFrameHost* evil_rfh = contents()->GetMainFrame(); | 1058 TestRenderFrameHost* evil_rfh = contents()->GetMainFrame(); |
1024 | 1059 |
1025 // Now let's simulate the evil page calling history.back(). | 1060 // Now let's simulate the evil page calling history.back(). |
1026 contents()->OnGoToEntryAtOffset(-1); | 1061 contents()->OnGoToEntryAtOffset(-1); |
| 1062 contents()->GetMainFrame()->PrepareForCommit(kUrl1); |
1027 // We should have a new pending RFH. | 1063 // We should have a new pending RFH. |
1028 // Note that in this case, the navigation has not committed, so evil_rfh will | 1064 // Note that in this case, the navigation has not committed, so evil_rfh will |
1029 // not be deleted yet. | 1065 // not be deleted yet. |
1030 EXPECT_NE(evil_rfh, contents()->GetPendingMainFrame()); | 1066 EXPECT_NE(evil_rfh, contents()->GetPendingMainFrame()); |
1031 EXPECT_NE(evil_rfh->GetRenderViewHost(), | 1067 EXPECT_NE(evil_rfh->GetRenderViewHost(), |
1032 contents()->GetPendingMainFrame()->GetRenderViewHost()); | 1068 contents()->GetPendingMainFrame()->GetRenderViewHost()); |
1033 | 1069 |
1034 // Before that RFH has committed, the evil page reloads itself. | 1070 // Before that RFH has committed, the evil page reloads itself. |
1035 FrameHostMsg_DidCommitProvisionalLoad_Params params; | 1071 FrameHostMsg_DidCommitProvisionalLoad_Params params; |
1036 params.page_id = 1; | 1072 params.page_id = 1; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 rfh1->GetSiteInstance()->increment_active_frame_count(); | 1136 rfh1->GetSiteInstance()->increment_active_frame_count(); |
1101 | 1137 |
1102 contents()->NavigateAndCommit(kUrl2); | 1138 contents()->NavigateAndCommit(kUrl2); |
1103 TestRenderFrameHost* rfh2 = main_test_rfh(); | 1139 TestRenderFrameHost* rfh2 = main_test_rfh(); |
1104 rfh2->GetSiteInstance()->increment_active_frame_count(); | 1140 rfh2->GetSiteInstance()->increment_active_frame_count(); |
1105 | 1141 |
1106 // 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 |
1107 // 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 |
1108 // (http://crbug.com/93427). | 1144 // (http://crbug.com/93427). |
1109 contents()->GetController().GoBack(); | 1145 contents()->GetController().GoBack(); |
1110 EXPECT_TRUE(rfh2->is_waiting_for_beforeunload_ack()); | 1146 EXPECT_TRUE(rfh2->IsWaitingForBeforeUnloadACK()); |
1111 contents()->ProceedWithCrossSiteNavigation(); | 1147 contents()->GetMainFrame()->PrepareForCommit(kUrl1); |
1112 EXPECT_FALSE(rfh2->is_waiting_for_beforeunload_ack()); | 1148 EXPECT_FALSE(rfh2->IsWaitingForBeforeUnloadACK()); |
1113 | 1149 |
1114 // The back navigation commits. | 1150 // The back navigation commits. |
1115 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); | 1151 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); |
1116 rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); | 1152 rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); |
1117 EXPECT_TRUE(rfh2->IsWaitingForUnloadACK()); | 1153 EXPECT_TRUE(rfh2->IsWaitingForUnloadACK()); |
1118 EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh2->rfh_state()); | 1154 EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh2->rfh_state()); |
1119 | 1155 |
1120 // We should be able to navigate forward. | 1156 // We should be able to navigate forward. |
1121 contents()->GetController().GoForward(); | 1157 contents()->GetController().GoForward(); |
1122 contents()->ProceedWithCrossSiteNavigation(); | 1158 contents()->GetMainFrame()->PrepareForCommit(kUrl2); |
1123 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); | 1159 const NavigationEntry* entry2 = contents()->GetController().GetPendingEntry(); |
1124 rfh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); | 1160 rfh2->SendNavigate(entry2->GetPageID(), entry2->GetURL()); |
1125 EXPECT_EQ(rfh2, main_test_rfh()); | 1161 EXPECT_EQ(rfh2, main_test_rfh()); |
1126 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state()); | 1162 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state()); |
1127 EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh1->rfh_state()); | 1163 EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh1->rfh_state()); |
1128 rfh1->OnSwappedOut(); | 1164 rfh1->OnSwappedOut(); |
1129 EXPECT_TRUE(rfh1->is_swapped_out()); | 1165 EXPECT_TRUE(rfh1->is_swapped_out()); |
1130 EXPECT_EQ(RenderFrameHostImpl::STATE_SWAPPED_OUT, rfh1->rfh_state()); | 1166 EXPECT_EQ(RenderFrameHostImpl::STATE_SWAPPED_OUT, rfh1->rfh_state()); |
1131 } | 1167 } |
1132 | 1168 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 EXPECT_TRUE(contents()->HasOpener()); | 1319 EXPECT_TRUE(contents()->HasOpener()); |
1284 | 1320 |
1285 // Navigate to a cross-site URL (different SiteInstance but same | 1321 // Navigate to a cross-site URL (different SiteInstance but same |
1286 // BrowsingInstance). | 1322 // BrowsingInstance). |
1287 contents()->NavigateAndCommit(kUrl2); | 1323 contents()->NavigateAndCommit(kUrl2); |
1288 TestRenderFrameHost* rfh2 = main_test_rfh(); | 1324 TestRenderFrameHost* rfh2 = main_test_rfh(); |
1289 EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance()); | 1325 EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance()); |
1290 | 1326 |
1291 // Start a back navigation so that rfh1 becomes the pending RFH. | 1327 // Start a back navigation so that rfh1 becomes the pending RFH. |
1292 contents()->GetController().GoBack(); | 1328 contents()->GetController().GoBack(); |
1293 contents()->ProceedWithCrossSiteNavigation(); | 1329 contents()->GetMainFrame()->PrepareForCommit(kUrl1); |
1294 | 1330 |
1295 // Disown the opener from rfh2. | 1331 // Disown the opener from rfh2. |
1296 rfh2->DidDisownOpener(); | 1332 rfh2->DidDisownOpener(); |
1297 | 1333 |
1298 // Ensure the opener is cleared. | 1334 // Ensure the opener is cleared. |
1299 EXPECT_FALSE(contents()->HasOpener()); | 1335 EXPECT_FALSE(contents()->HasOpener()); |
1300 | 1336 |
1301 // The back navigation commits. | 1337 // The back navigation commits. |
1302 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); | 1338 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); |
1303 rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); | 1339 rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); |
(...skipping 20 matching lines...) Expand all Loading... |
1324 | 1360 |
1325 // Navigate to a cross-site URL (different SiteInstance but same | 1361 // Navigate to a cross-site URL (different SiteInstance but same |
1326 // BrowsingInstance). | 1362 // BrowsingInstance). |
1327 contents()->NavigateAndCommit(kUrl2); | 1363 contents()->NavigateAndCommit(kUrl2); |
1328 TestRenderFrameHost* rfh2 = main_test_rfh(); | 1364 TestRenderFrameHost* rfh2 = main_test_rfh(); |
1329 EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance()); | 1365 EXPECT_NE(rfh1->GetSiteInstance(), rfh2->GetSiteInstance()); |
1330 | 1366 |
1331 // Commit a back navigation before the DidDisownOpener message arrives. | 1367 // Commit a back navigation before the DidDisownOpener message arrives. |
1332 // rfh1 will be kept alive because of the opener tab. | 1368 // rfh1 will be kept alive because of the opener tab. |
1333 contents()->GetController().GoBack(); | 1369 contents()->GetController().GoBack(); |
1334 contents()->ProceedWithCrossSiteNavigation(); | 1370 contents()->GetMainFrame()->PrepareForCommit(kUrl1); |
1335 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); | 1371 const NavigationEntry* entry1 = contents()->GetController().GetPendingEntry(); |
1336 rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); | 1372 rfh1->SendNavigate(entry1->GetPageID(), entry1->GetURL()); |
1337 | 1373 |
1338 // Disown the opener from rfh2. | 1374 // Disown the opener from rfh2. |
1339 rfh2->DidDisownOpener(); | 1375 rfh2->DidDisownOpener(); |
1340 EXPECT_FALSE(contents()->HasOpener()); | 1376 EXPECT_FALSE(contents()->HasOpener()); |
1341 } | 1377 } |
1342 | 1378 |
1343 // Test that we clean up swapped out RenderViewHosts when a process hosting | 1379 // Test that we clean up swapped out RenderViewHosts when a process hosting |
1344 // those associated RenderViews crashes. http://crbug.com/258993 | 1380 // those associated RenderViews crashes. http://crbug.com/258993 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 Details<RenderProcessHost::RendererClosedDetails>(&details)); | 1416 Details<RenderProcessHost::RendererClosedDetails>(&details)); |
1381 rvh1->set_render_view_created(false); | 1417 rvh1->set_render_view_created(false); |
1382 | 1418 |
1383 // Ensure that the swapped out RenderViewHost has been deleted. | 1419 // Ensure that the swapped out RenderViewHost has been deleted. |
1384 EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost( | 1420 EXPECT_FALSE(opener1_manager->GetSwappedOutRenderViewHost( |
1385 rvh1->GetSiteInstance())); | 1421 rvh1->GetSiteInstance())); |
1386 | 1422 |
1387 // Reload the initial tab. This should recreate the opener's swapped out RVH | 1423 // Reload the initial tab. This should recreate the opener's swapped out RVH |
1388 // in the original SiteInstance. | 1424 // in the original SiteInstance. |
1389 contents()->GetController().Reload(true); | 1425 contents()->GetController().Reload(true); |
| 1426 contents()->GetMainFrame()->PrepareForCommit(kUrl1); |
1390 EXPECT_EQ(opener1_manager->GetSwappedOutRenderViewHost( | 1427 EXPECT_EQ(opener1_manager->GetSwappedOutRenderViewHost( |
1391 rvh1->GetSiteInstance())->GetRoutingID(), | 1428 rvh1->GetSiteInstance())->GetRoutingID(), |
1392 test_rvh()->opener_route_id()); | 1429 test_rvh()->opener_route_id()); |
1393 } | 1430 } |
1394 | 1431 |
1395 // Test that RenderViewHosts created for WebUI navigations are properly | 1432 // Test that RenderViewHosts created for WebUI navigations are properly |
1396 // granted WebUI bindings even if an unprivileged swapped out RenderViewHost | 1433 // granted WebUI bindings even if an unprivileged swapped out RenderViewHost |
1397 // is in the same process (http://crbug.com/79918). | 1434 // is in the same process (http://crbug.com/79918). |
1398 TEST_F(RenderFrameHostManagerTest, EnableWebUIWithSwappedOutOpener) { | 1435 TEST_F(RenderFrameHostManagerTest, EnableWebUIWithSwappedOutOpener) { |
1399 set_should_create_webui(true); | 1436 set_should_create_webui(true); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1572 contents()->NavigateAndCommit(kUrl1); | 1609 contents()->NavigateAndCommit(kUrl1); |
1573 TestRenderFrameHost* rfh1 = contents()->GetMainFrame(); | 1610 TestRenderFrameHost* rfh1 = contents()->GetMainFrame(); |
1574 | 1611 |
1575 // Start to close the tab, but assume it's unresponsive. | 1612 // Start to close the tab, but assume it's unresponsive. |
1576 rfh1->render_view_host()->ClosePage(); | 1613 rfh1->render_view_host()->ClosePage(); |
1577 EXPECT_TRUE(rfh1->render_view_host()->is_waiting_for_close_ack()); | 1614 EXPECT_TRUE(rfh1->render_view_host()->is_waiting_for_close_ack()); |
1578 | 1615 |
1579 // Start a navigation to a new site. | 1616 // Start a navigation to a new site. |
1580 controller().LoadURL( | 1617 controller().LoadURL( |
1581 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 1618 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
| 1619 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 1620 switches::kEnableBrowserSideNavigation)) { |
| 1621 rfh1->PrepareForCommit(kUrl2); |
| 1622 } |
1582 EXPECT_TRUE(contents()->cross_navigation_pending()); | 1623 EXPECT_TRUE(contents()->cross_navigation_pending()); |
1583 | 1624 |
1584 // Simulate the unresponsiveness timer. The tab should close. | 1625 // Simulate the unresponsiveness timer. The tab should close. |
1585 contents()->RendererUnresponsive(rfh1->render_view_host()); | 1626 contents()->RendererUnresponsive(rfh1->render_view_host()); |
1586 EXPECT_TRUE(close_delegate.is_closed()); | 1627 EXPECT_TRUE(close_delegate.is_closed()); |
1587 } | 1628 } |
1588 | 1629 |
1589 // Tests that the RenderFrameHost is properly deleted when the SwapOutACK is | 1630 // Tests that the RenderFrameHost is properly deleted when the SwapOutACK is |
1590 // received. (SwapOut and the corresponding ACK always occur after commit.) | 1631 // received. (SwapOut and the corresponding ACK always occur after commit.) |
1591 // Also tests that an early SwapOutACK is properly ignored. | 1632 // Also tests that an early SwapOutACK is properly ignored. |
1592 TEST_F(RenderFrameHostManagerTest, DeleteFrameAfterSwapOutACK) { | 1633 TEST_F(RenderFrameHostManagerTest, DeleteFrameAfterSwapOutACK) { |
1593 const GURL kUrl1("http://www.google.com/"); | 1634 const GURL kUrl1("http://www.google.com/"); |
1594 const GURL kUrl2("http://www.chromium.org/"); | 1635 const GURL kUrl2("http://www.chromium.org/"); |
1595 | 1636 |
1596 // Navigate to the first page. | 1637 // Navigate to the first page. |
1597 contents()->NavigateAndCommit(kUrl1); | 1638 contents()->NavigateAndCommit(kUrl1); |
1598 TestRenderFrameHost* rfh1 = contents()->GetMainFrame(); | 1639 TestRenderFrameHost* rfh1 = contents()->GetMainFrame(); |
1599 RenderFrameHostDeletedObserver rfh_deleted_observer(rfh1); | 1640 RenderFrameHostDeletedObserver rfh_deleted_observer(rfh1); |
1600 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); | 1641 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); |
1601 | 1642 |
1602 // Navigate to new site, simulating onbeforeunload approval. | 1643 // Navigate to new site, simulating onbeforeunload approval. |
1603 controller().LoadURL( | 1644 controller().LoadURL( |
1604 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 1645 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
1605 base::TimeTicks now = base::TimeTicks::Now(); | 1646 contents()->GetMainFrame()->PrepareForCommit(kUrl2); |
1606 contents()->GetMainFrame()->OnMessageReceived( | |
1607 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); | |
1608 EXPECT_TRUE(contents()->cross_navigation_pending()); | 1647 EXPECT_TRUE(contents()->cross_navigation_pending()); |
1609 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); | 1648 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); |
1610 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); | 1649 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); |
1611 | 1650 |
1612 // Simulate the swap out ack, unexpectedly early (before commit). It should | 1651 // Simulate the swap out ack, unexpectedly early (before commit). It should |
1613 // have no effect. | 1652 // have no effect. |
1614 rfh1->OnSwappedOut(); | 1653 rfh1->OnSwappedOut(); |
1615 EXPECT_TRUE(contents()->cross_navigation_pending()); | 1654 EXPECT_TRUE(contents()->cross_navigation_pending()); |
1616 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); | 1655 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); |
1617 | 1656 |
(...skipping 27 matching lines...) Expand all Loading... |
1645 RenderFrameHostDeletedObserver rfh_deleted_observer(rfh1); | 1684 RenderFrameHostDeletedObserver rfh_deleted_observer(rfh1); |
1646 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); | 1685 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); |
1647 | 1686 |
1648 // Increment the number of active frames in SiteInstanceImpl so that rfh1 is | 1687 // Increment the number of active frames in SiteInstanceImpl so that rfh1 is |
1649 // not deleted on swap out. | 1688 // not deleted on swap out. |
1650 rfh1->GetSiteInstance()->increment_active_frame_count(); | 1689 rfh1->GetSiteInstance()->increment_active_frame_count(); |
1651 | 1690 |
1652 // Navigate to new site, simulating onbeforeunload approval. | 1691 // Navigate to new site, simulating onbeforeunload approval. |
1653 controller().LoadURL( | 1692 controller().LoadURL( |
1654 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 1693 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
1655 base::TimeTicks now = base::TimeTicks::Now(); | 1694 contents()->GetMainFrame()->PrepareForCommit(kUrl2); |
1656 contents()->GetMainFrame()->OnMessageReceived( | |
1657 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); | |
1658 EXPECT_TRUE(contents()->cross_navigation_pending()); | 1695 EXPECT_TRUE(contents()->cross_navigation_pending()); |
1659 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); | 1696 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); |
1660 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); | 1697 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); |
1661 | 1698 |
1662 // The new page commits. | 1699 // The new page commits. |
1663 contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED); | 1700 contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED); |
1664 EXPECT_FALSE(contents()->cross_navigation_pending()); | 1701 EXPECT_FALSE(contents()->cross_navigation_pending()); |
1665 EXPECT_EQ(rfh2, contents()->GetMainFrame()); | 1702 EXPECT_EQ(rfh2, contents()->GetMainFrame()); |
1666 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL); | 1703 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL); |
1667 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state()); | 1704 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state()); |
(...skipping 22 matching lines...) Expand all Loading... |
1690 RenderFrameHostDeletedObserver rfh_deleted_observer(rfh1); | 1727 RenderFrameHostDeletedObserver rfh_deleted_observer(rfh1); |
1691 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); | 1728 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh1->rfh_state()); |
1692 | 1729 |
1693 // Increment the number of active frames in SiteInstanceImpl so that rfh1 is | 1730 // Increment the number of active frames in SiteInstanceImpl so that rfh1 is |
1694 // not deleted on swap out. | 1731 // not deleted on swap out. |
1695 rfh1->GetSiteInstance()->increment_active_frame_count(); | 1732 rfh1->GetSiteInstance()->increment_active_frame_count(); |
1696 | 1733 |
1697 // Navigate to new site, simulating onbeforeunload approval. | 1734 // Navigate to new site, simulating onbeforeunload approval. |
1698 controller().LoadURL( | 1735 controller().LoadURL( |
1699 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); | 1736 kUrl2, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
1700 base::TimeTicks now = base::TimeTicks::Now(); | 1737 rfh1->PrepareForCommit(kUrl2); |
1701 rfh1->OnMessageReceived( | |
1702 FrameHostMsg_BeforeUnload_ACK(0, true, now, now)); | |
1703 EXPECT_TRUE(contents()->cross_navigation_pending()); | 1738 EXPECT_TRUE(contents()->cross_navigation_pending()); |
1704 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); | 1739 TestRenderFrameHost* rfh2 = contents()->GetPendingMainFrame(); |
1705 | 1740 |
1706 // The new page commits. | 1741 // The new page commits. |
1707 contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED); | 1742 contents()->TestDidNavigate(rfh2, 1, kUrl2, ui::PAGE_TRANSITION_TYPED); |
1708 EXPECT_FALSE(contents()->cross_navigation_pending()); | 1743 EXPECT_FALSE(contents()->cross_navigation_pending()); |
1709 EXPECT_EQ(rfh2, contents()->GetMainFrame()); | 1744 EXPECT_EQ(rfh2, contents()->GetMainFrame()); |
1710 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL); | 1745 EXPECT_TRUE(contents()->GetPendingMainFrame() == NULL); |
1711 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state()); | 1746 EXPECT_EQ(RenderFrameHostImpl::STATE_DEFAULT, rfh2->rfh_state()); |
1712 EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh1->rfh_state()); | 1747 EXPECT_EQ(RenderFrameHostImpl::STATE_PENDING_SWAP_OUT, rfh1->rfh_state()); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(), | 1821 contents()->GetMainFrame()->GetProcess()->GetNextRoutingID(), |
1787 std::string("frame_name"), SandboxFlags::NONE); | 1822 std::string("frame_name"), SandboxFlags::NONE); |
1788 RenderFrameHostManager* manager = | 1823 RenderFrameHostManager* manager = |
1789 contents()->GetFrameTree()->root()->child_at(0)->render_manager(); | 1824 contents()->GetFrameTree()->root()->child_at(0)->render_manager(); |
1790 | 1825 |
1791 // 1) The first navigation. -------------------------- | 1826 // 1) The first navigation. -------------------------- |
1792 NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1, | 1827 NavigationEntryImpl entry1(NULL /* instance */, -1 /* page_id */, kUrl1, |
1793 Referrer(), base::string16() /* title */, | 1828 Referrer(), base::string16() /* title */, |
1794 ui::PAGE_TRANSITION_TYPED, | 1829 ui::PAGE_TRANSITION_TYPED, |
1795 false /* is_renderer_init */); | 1830 false /* is_renderer_init */); |
1796 host = manager->Navigate(entry1); | 1831 host = GetFrameHostForNavigation(manager, entry1); |
1797 | 1832 |
1798 // The RenderFrameHost created in Init will be reused. | 1833 // The RenderFrameHost created in Init will be reused. |
1799 EXPECT_TRUE(host == manager->current_frame_host()); | 1834 EXPECT_TRUE(host == manager->current_frame_host()); |
1800 EXPECT_FALSE(manager->pending_frame_host()); | 1835 EXPECT_FALSE(GetPendingFrameHost(manager)); |
1801 | 1836 |
1802 // Commit. | 1837 // Commit. |
1803 manager->DidNavigateFrame(host, true); | 1838 manager->DidNavigateFrame(host, true); |
1804 // Commit to SiteInstance should be delayed until RenderFrame commit. | 1839 // Commit to SiteInstance should be delayed until RenderFrame commit. |
1805 EXPECT_TRUE(host == manager->current_frame_host()); | 1840 EXPECT_TRUE(host == manager->current_frame_host()); |
1806 ASSERT_TRUE(host); | 1841 ASSERT_TRUE(host); |
1807 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); | 1842 EXPECT_TRUE(host->GetSiteInstance()->HasSite()); |
1808 | 1843 |
1809 // 2) Cross-site navigate to next site. -------------- | 1844 // 2) Cross-site navigate to next site. -------------- |
1810 NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, | 1845 NavigationEntryImpl entry2(NULL /* instance */, -1 /* page_id */, kUrl2, |
1811 Referrer(kUrl1, blink::WebReferrerPolicyDefault), | 1846 Referrer(kUrl1, blink::WebReferrerPolicyDefault), |
1812 base::string16() /* title */, | 1847 base::string16() /* title */, |
1813 ui::PAGE_TRANSITION_LINK, | 1848 ui::PAGE_TRANSITION_LINK, |
1814 false /* is_renderer_init */); | 1849 false /* is_renderer_init */); |
1815 host = manager->Navigate(entry2); | 1850 host = GetFrameHostForNavigation(manager, entry2); |
1816 | 1851 |
1817 // A new RenderFrameHost should be created. | 1852 // A new RenderFrameHost should be created. |
1818 EXPECT_TRUE(manager->pending_frame_host()); | 1853 EXPECT_TRUE(GetPendingFrameHost(manager)); |
1819 ASSERT_EQ(host, manager->pending_frame_host()); | 1854 ASSERT_EQ(host, GetPendingFrameHost(manager)); |
1820 ASSERT_NE(manager->current_frame_host(), manager->pending_frame_host()); | 1855 ASSERT_NE(manager->current_frame_host(), GetPendingFrameHost(manager)); |
1821 EXPECT_FALSE(contents()->cross_navigation_pending()) | 1856 EXPECT_FALSE(contents()->cross_navigation_pending()) |
1822 << "There should be no top-level pending navigation."; | 1857 << "There should be no top-level pending navigation."; |
1823 | 1858 |
1824 RenderFrameHostDeletedObserver delete_watcher(manager->pending_frame_host()); | 1859 RenderFrameHostDeletedObserver delete_watcher(GetPendingFrameHost(manager)); |
1825 EXPECT_FALSE(delete_watcher.deleted()); | 1860 EXPECT_FALSE(delete_watcher.deleted()); |
1826 | 1861 |
1827 // Extend the lifetime of the child frame's SiteInstance, pretending | 1862 // Extend the lifetime of the child frame's SiteInstance, pretending |
1828 // that there is another reference to it. | 1863 // that there is another reference to it. |
1829 scoped_refptr<SiteInstanceImpl> site_instance = | 1864 scoped_refptr<SiteInstanceImpl> site_instance = |
1830 manager->pending_frame_host()->GetSiteInstance(); | 1865 GetPendingFrameHost(manager)->GetSiteInstance(); |
1831 EXPECT_TRUE(site_instance->HasSite()); | 1866 EXPECT_TRUE(site_instance->HasSite()); |
1832 EXPECT_NE(site_instance, contents()->GetSiteInstance()); | 1867 EXPECT_NE(site_instance, contents()->GetSiteInstance()); |
1833 EXPECT_EQ(1U, site_instance->active_frame_count()); | 1868 EXPECT_EQ(1U, site_instance->active_frame_count()); |
1834 site_instance->increment_active_frame_count(); | 1869 site_instance->increment_active_frame_count(); |
1835 EXPECT_EQ(2U, site_instance->active_frame_count()); | 1870 EXPECT_EQ(2U, site_instance->active_frame_count()); |
1836 | 1871 |
1837 // Now detach the child FrameTreeNode. This should kill the pending host. | 1872 // Now detach the child FrameTreeNode. This should kill the pending host. |
1838 manager->current_frame_host()->OnMessageReceived( | 1873 manager->current_frame_host()->OnMessageReceived( |
1839 FrameHostMsg_Detach(manager->current_frame_host()->GetRoutingID())); | 1874 FrameHostMsg_Detach(manager->current_frame_host()->GetRoutingID())); |
1840 | 1875 |
1841 EXPECT_TRUE(delete_watcher.deleted()); | 1876 EXPECT_TRUE(delete_watcher.deleted()); |
1842 | 1877 |
1843 EXPECT_EQ(1U, site_instance->active_frame_count()); | 1878 EXPECT_EQ(1U, site_instance->active_frame_count()); |
1844 site_instance->decrement_active_frame_count(); | 1879 site_instance->decrement_active_frame_count(); |
1845 | 1880 |
1846 #if 0 | 1881 #if 0 |
1847 // TODO(nick): Currently a proxy to the removed frame lingers in the parent. | 1882 // TODO(nick): Currently a proxy to the removed frame lingers in the parent. |
1848 // Enable this assert below once the proxies to the subframe are correctly | 1883 // Enable this assert below once the proxies to the subframe are correctly |
1849 // cleaned up after detach. http://crbug.com/444955. | 1884 // cleaned up after detach. http://crbug.com/444955. |
1850 ASSERT_TRUE(site_instance->HasOneRef()) | 1885 ASSERT_TRUE(site_instance->HasOneRef()) |
1851 << "This SiteInstance should be destroyable now."; | 1886 << "This SiteInstance should be destroyable now."; |
1852 #endif | 1887 #endif |
1853 } | 1888 } |
1854 | 1889 |
1855 } // namespace content | 1890 } // namespace content |
OLD | NEW |