diff --git a/chrome/browser/background/background_contents.cc b/chrome/browser/background/background_contents.cc index bf94280656bfba..675760ea599ffb 100644 --- a/chrome/browser/background/background_contents.cc +++ b/chrome/browser/background/background_contents.cc @@ -41,6 +41,7 @@ BackgroundContents::BackgroundContents( WebContents::CreateParams create_params(profile_, site_instance); create_params.routing_id = routing_id; create_params.main_frame_routing_id = main_frame_routing_id; + create_params.renderer_initiated_creation = true; if (session_storage_namespace) { content::SessionStorageNamespaceMap session_storage_namespace_map; session_storage_namespace_map.insert( diff --git a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc index fa79aa8bfdf6c3..111844d8622d69 100644 --- a/chrome/browser/geolocation/geolocation_permission_context_unittest.cc +++ b/chrome/browser/geolocation/geolocation_permission_context_unittest.cc @@ -220,8 +220,7 @@ void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal( } void GeolocationPermissionContextTests::AddNewTab(const GURL& url) { - content::WebContents* new_tab = content::WebContents::Create( - content::WebContents::CreateParams(profile())); + content::WebContents* new_tab = CreateTestWebContents(); new_tab->GetController().LoadURL( url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string()); content::RenderFrameHostTester::For(new_tab->GetMainFrame()) diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc index 75cdeb1000055b..ca7862210c6aeb 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_interactive_uitest.cc @@ -13,6 +13,7 @@ #include "components/autofill/content/browser/content_autofill_driver_factory.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/test_autofill_external_delegate.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/test_utils.h" @@ -42,8 +43,6 @@ class TestAutofillExternalDelegate : public AutofillExternalDelegate { if (message_loop_runner_.get()) message_loop_runner_->Quit(); - - AutofillExternalDelegate::OnPopupHidden(); } void WaitForPopupHidden() { @@ -90,7 +89,10 @@ class AutofillPopupControllerBrowserTest // Normally the WebContents will automatically delete the delegate, but here // the delegate is owned by this test, so we have to manually destroy. - void WebContentsDestroyed() override { autofill_external_delegate_.reset(); } + void RenderFrameDeleted(content::RenderFrameHost* rfh) override { + if (!rfh->GetParent()) + autofill_external_delegate_.reset(); + } protected: scoped_ptr autofill_external_delegate_; diff --git a/content/browser/frame_host/frame_tree_unittest.cc b/content/browser/frame_host/frame_tree_unittest.cc index 8fdcf71e3fc9dc..ad4fd7567fbec6 100644 --- a/content/browser/frame_host/frame_tree_unittest.cc +++ b/content/browser/frame_host/frame_tree_unittest.cc @@ -69,9 +69,13 @@ class TreeWalkingWebContentsLogger : public WebContentsObserver { void RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) override { + // TODO(nasko): Re-enable this logging once RenderFrameHostChanged observer + // methods are fixed. See https://crbug.com/450799. + /* if (old_host) LogWhatHappened("RenderFrameChanged(old)", old_host); LogWhatHappened("RenderFrameChanged(new)", new_host); + */ } void RenderFrameDeleted(RenderFrameHost* render_frame_host) override { @@ -229,11 +233,13 @@ TEST_F(FrameTreeTest, ObserverWalksTreeAfterCrash) { EXPECT_EQ("RenderFrameCreated(23) -> 1: [22: [], 23: []]", activity.GetLog()); // Crash the renderer - main_rfh()->OnMessageReceived(FrameHostMsg_RenderProcessGone( - 0, base::TERMINATION_STATUS_PROCESS_CRASHED, -1)); + main_test_rfh()->OnMessageReceived(FrameHostMsg_RenderProcessGone( + main_test_rfh()->GetRoutingID(), base::TERMINATION_STATUS_PROCESS_CRASHED, + -1)); EXPECT_EQ( "RenderFrameDeleted(22) -> 1: []\n" "RenderFrameDeleted(23) -> 1: []\n" + "RenderFrameDeleted(1) -> 1: []\n" "RenderProcessGone -> 1: []", activity.GetLog()); } diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index e6cc05197d3a25..6b248ecd6ea08e 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc @@ -184,7 +184,7 @@ RenderFrameHostImpl::~RenderFrameHostImpl() { g_routing_id_frame_map.Get().erase( RenderFrameHostID(GetProcess()->GetID(), routing_id_)); - if (delegate_) + if (delegate_ && render_frame_created_) delegate_->RenderFrameDeleted(this); FrameAccessibility::GetInstance()->OnRenderFrameHostDestroyed(this); @@ -619,6 +619,15 @@ bool RenderFrameHostImpl::IsRenderFrameLive() { } void RenderFrameHostImpl::SetRenderFrameCreated(bool created) { + // If the current status is different than the new status, the delegate + // needs to be notified. + if (delegate_ && (created != render_frame_created_)) { + if (created) + delegate_->RenderFrameCreated(this); + else + delegate_->RenderFrameDeleted(this); + } + render_frame_created_ = created; if (created && render_widget_host_) render_widget_host_->InitForFrame(); @@ -669,14 +678,11 @@ void RenderFrameHostImpl::OnCreateChildFrame(int new_routing_id, if (!new_frame) return; + new_frame->frame_tree_node()->set_sandbox_flags(sandbox_flags); + // We know that the RenderFrame has been created in this case, immediately // after the CreateChildFrame IPC was sent. new_frame->SetRenderFrameCreated(true); - - new_frame->frame_tree_node()->set_sandbox_flags(sandbox_flags); - - if (delegate_) - delegate_->RenderFrameCreated(new_frame); } void RenderFrameHostImpl::OnDetach() { @@ -1049,9 +1055,6 @@ void RenderFrameHostImpl::OnRenderProcessGone(int status, int exit_code) { static_cast(status); } - SetRenderFrameCreated(false); - InvalidateMojoConnection(); - // Reset frame tree state associated with this process. This must happen // before RenderViewTerminated because observers expect the subframes of any // affected frames to be cleared first. @@ -1061,6 +1064,11 @@ void RenderFrameHostImpl::OnRenderProcessGone(int status, int exit_code) { if (!is_swapped_out()) frame_tree_node_->ResetForNewProcess(); + // Reset state for the current RenderFrameHost once the FrameTreeNode has been + // reset. + SetRenderFrameCreated(false); + InvalidateMojoConnection(); + if (frame_tree_node_->IsMainFrame()) { // RenderViewHost/RenderWidgetHost needs to reset some stuff. render_view_host_->RendererExited( diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 0cd3b53b3c42c4..f9e2bf976fcbe8 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc @@ -87,6 +87,10 @@ RenderFrameHostManager::~RenderFrameHostManager() { // the current RenderFrameHost and uses it during its destructor. STLDeleteValues(&proxy_hosts_); + // Release the WebUI prior to resetting the current RenderFrameHost, as the + // WebUI accesses the RenderFrameHost during cleanup. + web_ui_.reset(); + // We should always have a current RenderFrameHost except in some tests. SetRenderFrameHost(scoped_ptr()); } @@ -1411,13 +1415,6 @@ scoped_ptr RenderFrameHostManager::CreateRenderFrame( if (success) { if (view_routing_id_ptr) *view_routing_id_ptr = render_view_host->GetRoutingID(); - - // A brand new RenderFrame was created by one of the Init calls above. - // Announce it to observers. - if (swapped_out) - render_frame_delegate_->RenderFrameCreated(proxy->render_frame_host()); - else - render_frame_delegate_->RenderFrameCreated(new_render_frame_host.get()); } } diff --git a/content/browser/manifest/manifest_manager_host.cc b/content/browser/manifest/manifest_manager_host.cc index d32a8c349cba21..14d07e203ee3a9 100644 --- a/content/browser/manifest/manifest_manager_host.cc +++ b/content/browser/manifest/manifest_manager_host.cc @@ -4,6 +4,7 @@ #include "content/browser/manifest/manifest_manager_host.h" +#include "base/stl_util.h" #include "content/common/manifest_manager_messages.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -30,6 +31,7 @@ ManifestManagerHost::ManifestManagerHost(WebContents* web_contents) } ManifestManagerHost::~ManifestManagerHost() { + STLDeleteValues(&pending_callbacks_); } ManifestManagerHost::CallbackMap* ManifestManagerHost::GetCallbackMapForFrame( diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 8233aaed82b665..190545d1e8e519 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -317,6 +317,11 @@ bool RenderViewHostImpl::CreateRenderView( // Let our delegate know that we created a RenderView. delegate_->RenderViewCreated(this); + // Since this method creates the main RenderFrame in the renderer process, + // set the proper state on its corresponding RenderFrameHost. + RenderFrameHostImpl::FromID(GetProcess()->GetID(), main_frame_routing_id_) + ->SetRenderFrameCreated(true); + return true; } diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index b12ae2164ac6d2..8ca6671d35aa10 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -406,14 +406,10 @@ WebContentsImpl::~WebContentsImpl() { // Manually call the observer methods for the root frame tree node. RenderFrameHostManager* root = GetRenderManager(); - if (root->pending_frame_host()) { - FOR_EACH_OBSERVER(WebContentsObserver, - observers_, - RenderFrameDeleted(root->pending_frame_host())); - } - FOR_EACH_OBSERVER(WebContentsObserver, - observers_, - RenderFrameDeleted(root->current_frame_host())); + + if (root->pending_frame_host()) + root->pending_frame_host()->SetRenderFrameCreated(false); + root->current_frame_host()->SetRenderFrameCreated(false); if (root->pending_render_view_host()) { FOR_EACH_OBSERVER(WebContentsObserver, @@ -1265,6 +1261,14 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) { for (size_t i = 0; i < g_created_callbacks.Get().size(); i++) g_created_callbacks.Get().at(i).Run(this); + + // If the WebContents creation was renderer-initiated, it means that the + // corresponding RenderView and main RenderFrame have already been created. + // Ensure observers are notified about this. + if (params.renderer_initiated_creation) { + RenderViewCreated(GetRenderViewHost()); + GetRenderManager()->current_frame_host()->SetRenderFrameCreated(true); + } } void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) { @@ -1594,6 +1598,7 @@ void WebContentsImpl::CreateNewWindow( create_params.opener_suppressed = params.opener_suppressed; if (params.disposition == NEW_BACKGROUND_TAB) create_params.initially_hidden = true; + create_params.renderer_initiated_creation = true; WebContentsImpl* new_contents = NULL; if (!is_guest) { @@ -1607,7 +1612,6 @@ void WebContentsImpl::CreateNewWindow( new_contents->GetController().SetSessionStorageNamespace( partition_id, session_storage_namespace); - new_contents->RenderViewCreated(new_contents->GetRenderViewHost()); // Save the window for later if we're not suppressing the opener (since it // will be shown immediately). @@ -3663,14 +3667,6 @@ void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { FOR_EACH_OBSERVER( WebContentsObserver, observers_, RenderViewCreated(render_view_host)); - // We tell the observers now instead of when the main RenderFrameHostImpl is - // constructed because otherwise it would be too early (i.e. IPCs sent to the - // frame would be dropped because it's not created yet). - RenderFrameHost* main_frame = render_view_host->GetMainFrame(); - FOR_EACH_OBSERVER( - WebContentsObserver, observers_, RenderFrameCreated(main_frame)); - SetAccessibilityModeOnFrame(accessibility_mode_, main_frame); - DevToolsManager::GetInstance()->RenderViewCreated(this, render_view_host); } @@ -3704,10 +3700,6 @@ void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) { void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh, base::TerminationStatus status, int error_code) { - // TODO(nasko): This isn't ideal; the termination process should be handled by - // RenderFrameDeleted(). See http://crbug.com/455943. - ClearPowerSaveBlockers(rvh->GetMainFrame()); - if (rvh != GetRenderViewHost()) { // The pending page's RenderViewHost is gone. return; diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index ab40bcd466f743..5f25a5368e7ec2 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc @@ -520,6 +520,7 @@ TEST_F(WebContentsImplTest, CrossSiteBoundaries) { } // DidNavigate from the pending page + pending_rfh->PrepareForCommit(url2); contents()->TestDidNavigate( pending_rfh, 1, url2, ui::PAGE_TRANSITION_TYPED); SiteInstance* instance2 = contents()->GetSiteInstance(); diff --git a/content/public/browser/web_contents.cc b/content/public/browser/web_contents.cc index 676841113d404d..aece7c630ada1b 100644 --- a/content/public/browser/web_contents.cc +++ b/content/public/browser/web_contents.cc @@ -17,7 +17,8 @@ WebContents::CreateParams::CreateParams(BrowserContext* context) main_frame_routing_id(MSG_ROUTING_NONE), initially_hidden(false), guest_delegate(nullptr), - context(nullptr) {} + context(nullptr), + renderer_initiated_creation(false) {} WebContents::CreateParams::CreateParams( BrowserContext* context, SiteInstance* site) @@ -29,7 +30,8 @@ WebContents::CreateParams::CreateParams( main_frame_routing_id(MSG_ROUTING_NONE), initially_hidden(false), guest_delegate(nullptr), - context(nullptr) {} + context(nullptr), + renderer_initiated_creation(false) {} WebContents::CreateParams::~CreateParams() { } diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index 879e8d8513c03f..493abd8f0d4b29 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h @@ -122,6 +122,12 @@ class WebContents : public PageNavigator, // Used to specify the location context which display the new view should // belong. This can be nullptr if not needed. gfx::NativeView context; + + // Used to specify that the new WebContents creation is driven by the + // renderer process. In this case, the renderer-side objects, such as + // RenderFrame, have already been created on the renderer side, and + // WebContents construction should take this into account. + bool renderer_initiated_creation; }; // Creates a new WebContents. diff --git a/content/public/test/web_contents_observer_sanity_checker.cc b/content/public/test/web_contents_observer_sanity_checker.cc index 554992a9716d3e..e59998baf7fe54 100644 --- a/content/public/test/web_contents_observer_sanity_checker.cc +++ b/content/public/test/web_contents_observer_sanity_checker.cc @@ -4,7 +4,9 @@ #include "content/public/test/web_contents_observer_sanity_checker.h" +#include "base/debug/stack_trace.h" #include "base/strings/stringprintf.h" +#include "content/common/frame_messages.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/site_instance.h" @@ -35,17 +37,11 @@ void WebContentsObserverSanityChecker::RenderFrameCreated( std::make_pair(render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()); bool frame_exists = !live_routes_.insert(routing_pair).second; - bool dead_already = deleted_routes_.count(routing_pair) != 0; + deleted_routes_.erase(routing_pair); if (frame_exists) { -// TODO(nick): Disabled because of http://crbug.com/425397 -#if 0 CHECK(false) << "RenderFrameCreated called more than once for routing pair:" << Format(render_frame_host); -#endif - } else if (dead_already) { - CHECK(false) << "RenderFrameCreated called for routing pair that was " - << "previously deleted: " << Format(render_frame_host); } } @@ -82,14 +78,17 @@ void WebContentsObserverSanityChecker::RenderFrameHostChanged( RenderFrameHost* old_host, RenderFrameHost* new_host) { CHECK(new_host); - if (old_host) - AssertFrameExists(old_host); - AssertFrameExists(new_host); + CHECK_NE(new_host, old_host); + + // TODO(nasko): Implement consistency checking for RenderFrameHostChanged + // in follow up CL. } void WebContentsObserverSanityChecker::FrameDeleted( RenderFrameHost* render_frame_host) { - AssertFrameExists(render_frame_host); + // A frame can be deleted before RenderFrame in the renderer process is + // created, so there is not much that can be enforced here. + CHECK(!web_contents_destroyed_); } void WebContentsObserverSanityChecker::DidStartProvisionalLoadForFrame( @@ -97,14 +96,14 @@ void WebContentsObserverSanityChecker::DidStartProvisionalLoadForFrame( const GURL& validated_url, bool is_error_page, bool is_iframe_srcdoc) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidCommitProvisionalLoadForFrame( RenderFrameHost* render_frame_host, const GURL& url, ui::PageTransition transition_type) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidFailProvisionalLoad( @@ -112,7 +111,7 @@ void WebContentsObserverSanityChecker::DidFailProvisionalLoad( const GURL& validated_url, int error_code, const base::string16& error_description) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidNavigateMainFrame( @@ -125,7 +124,7 @@ void WebContentsObserverSanityChecker::DidNavigateAnyFrame( RenderFrameHost* render_frame_host, const LoadCommittedDetails& details, const FrameNavigateParams& params) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DocumentAvailableInMainFrame() { @@ -138,13 +137,13 @@ void WebContentsObserverSanityChecker::DocumentOnLoadCompletedInMainFrame() { void WebContentsObserverSanityChecker::DocumentLoadedInFrame( RenderFrameHost* render_frame_host) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidFinishLoad( RenderFrameHost* render_frame_host, const GURL& validated_url) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidFailLoad( @@ -152,13 +151,13 @@ void WebContentsObserverSanityChecker::DidFailLoad( const GURL& validated_url, int error_code, const base::string16& error_description) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidGetRedirectForResourceRequest( RenderFrameHost* render_frame_host, const ResourceRedirectDetails& details) { - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); } void WebContentsObserverSanityChecker::DidOpenRequestedURL( @@ -168,15 +167,22 @@ void WebContentsObserverSanityChecker::DidOpenRequestedURL( const Referrer& referrer, WindowOpenDisposition disposition, ui::PageTransition transition) { - AssertFrameExists(source_render_frame_host); + AssertRenderFrameExists(source_render_frame_host); } bool WebContentsObserverSanityChecker::OnMessageReceived( const IPC::Message& message, RenderFrameHost* render_frame_host) { + // TODO(nasko): FrameHostMsg_RenderProcessGone is delivered to + // WebContentsObserver since RenderFrameHost allows the delegate to handle + // the message first. This shouldn't happen, but for now handle it here. + // https://crbug.com/450799 + if (message.type() == FrameHostMsg_RenderProcessGone::ID) + return false; + #if !defined(OS_MACOSX) // TODO(avi): Disabled because of http://crbug.com/445054 - AssertFrameExists(render_frame_host); + AssertRenderFrameExists(render_frame_host); #endif return false; } @@ -190,20 +196,21 @@ WebContentsObserverSanityChecker::WebContentsObserverSanityChecker( WebContents* web_contents) : WebContentsObserver(web_contents), web_contents_destroyed_(false) { // Prime the pump with the initial objects. + // TODO(nasko): Investigate why this is needed. RenderViewCreated(web_contents->GetRenderViewHost()); - RenderFrameCreated(web_contents->GetMainFrame()); } WebContentsObserverSanityChecker::~WebContentsObserverSanityChecker() { CHECK(web_contents_destroyed_); } -void WebContentsObserverSanityChecker::AssertFrameExists( +void WebContentsObserverSanityChecker::AssertRenderFrameExists( RenderFrameHost* render_frame_host) { CHECK(!web_contents_destroyed_); std::pair routing_pair = std::make_pair(render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID()); + bool render_frame_created_happened = live_routes_.count(routing_pair) != 0; bool render_frame_deleted_happened = deleted_routes_.count(routing_pair) != 0; @@ -218,13 +225,13 @@ void WebContentsObserverSanityChecker::AssertFrameExists( } void WebContentsObserverSanityChecker::AssertMainFrameExists() { - AssertFrameExists(web_contents()->GetMainFrame()); + AssertRenderFrameExists(web_contents()->GetMainFrame()); } std::string WebContentsObserverSanityChecker::Format( RenderFrameHost* render_frame_host) { return base::StringPrintf( - "(%d, %d -> %s )", render_frame_host->GetProcess()->GetID(), + "(%d, %d -> %s)", render_frame_host->GetProcess()->GetID(), render_frame_host->GetRoutingID(), render_frame_host->GetSiteInstance()->GetSiteURL().spec().c_str()); } diff --git a/content/public/test/web_contents_observer_sanity_checker.h b/content/public/test/web_contents_observer_sanity_checker.h index 2d702d0859e341..b8c3b6118ce658 100644 --- a/content/public/test/web_contents_observer_sanity_checker.h +++ b/content/public/test/web_contents_observer_sanity_checker.h @@ -84,11 +84,12 @@ class WebContentsObserverSanityChecker : public WebContentsObserver, ~WebContentsObserverSanityChecker() override; std::string Format(RenderFrameHost* render_frame_host); - void AssertFrameExists(RenderFrameHost* render_frame_host); + void AssertRenderFrameExists(RenderFrameHost* render_frame_host); void AssertMainFrameExists(); std::set> live_routes_; std::set> deleted_routes_; + bool web_contents_destroyed_; DISALLOW_COPY_AND_ASSIGN(WebContentsObserverSanityChecker); diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 9249d2609ab7ce..988681c5e04102 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc @@ -54,9 +54,13 @@ TestRenderFrameHost::TestRenderFrameHost(SiteInstance* site_instance, child_creation_observer_(delegate ? delegate->GetAsWebContents() : NULL), contents_mime_type_("text/html"), simulate_history_list_was_cleared_(false) { + if (frame_tree_node_->IsMainFrame()) + SetRenderFrameCreated(true); } -TestRenderFrameHost::~TestRenderFrameHost() {} +TestRenderFrameHost::~TestRenderFrameHost() { + SetRenderFrameCreated(false); +} TestRenderViewHost* TestRenderFrameHost::GetRenderViewHost() { return static_cast( @@ -107,6 +111,11 @@ void TestRenderFrameHost::SendNavigateWithTransitionAndResponseCode( // DidStartProvisionalLoad may delete the pending entry that holds |url|, // so we keep a copy of it to use in SendNavigateWithParameters. GURL url_copy(url); + + // Ensure that the RenderFrameCreated notification has been sent to observers + // before navigating the frame. + SetRenderFrameCreated(true); + OnDidStartProvisionalLoadForFrame(url_copy, false); SendNavigateWithParameters(page_id, url_copy, transition, url_copy, response_code, 0, std::vector()); @@ -116,6 +125,10 @@ void TestRenderFrameHost::SendNavigateWithOriginalRequestURL( int page_id, const GURL& url, const GURL& original_request_url) { + // Ensure that the RenderFrameCreated notification has been sent to observers + // before navigating the frame. + SetRenderFrameCreated(true); + OnDidStartProvisionalLoadForFrame(url, false); SendNavigateWithParameters(page_id, url, ui::PAGE_TRANSITION_LINK, original_request_url, 200, 0, std::vector()); diff --git a/content/test/test_web_contents.cc b/content/test/test_web_contents.cc index 93aec71aed35fc..d3a1c1d1e4f7fd 100644 --- a/content/test/test_web_contents.cc +++ b/content/test/test_web_contents.cc @@ -38,6 +38,7 @@ TestWebContents* TestWebContents::Create(BrowserContext* browser_context, SiteInstance* instance) { TestWebContents* test_web_contents = new TestWebContents(browser_context); test_web_contents->Init(WebContents::CreateParams(browser_context, instance)); + test_web_contents->RenderFrameCreated(test_web_contents->GetMainFrame()); return test_web_contents; }