| Index: content/browser/frame_host/render_frame_host_manager_unittest.cc
|
| diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
|
| index f534336b4128e1b5d5e5a19d19c066d4cea5516f..863971cbf25505ff6a8bd4600c7d48530453638c 100644
|
| --- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
|
| +++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
|
| @@ -51,6 +51,20 @@
|
| namespace content {
|
| namespace {
|
|
|
| +// Helper to check that the provided RenderProcessHost received exactly one
|
| +// page focus message with the provided focus and routing ID values.
|
| +void VerifyPageFocusMessage(MockRenderProcessHost* rph,
|
| + bool expected_focus,
|
| + int expected_routing_id) {
|
| + const IPC::Message* message =
|
| + rph->sink().GetUniqueMessageMatching(InputMsg_SetFocus::ID);
|
| + EXPECT_TRUE(message);
|
| + EXPECT_EQ(expected_routing_id, message->routing_id());
|
| + InputMsg_SetFocus::Param params;
|
| + EXPECT_TRUE(InputMsg_SetFocus::Read(message, ¶ms));
|
| + EXPECT_EQ(expected_focus, base::get<0>(params));
|
| +}
|
| +
|
| class RenderFrameHostManagerTestWebUIControllerFactory
|
| : public WebUIControllerFactory {
|
| public:
|
| @@ -2486,7 +2500,7 @@ TEST_F(RenderFrameHostManagerTest, TraverseComplexOpenerChain) {
|
| // current page.
|
| //
|
| // TODO(alexmos): Move this test to FrameTree unit tests once NavigateToEntry
|
| -// is moved to a common place.
|
| +// is moved to a common place. See https://crbug.com/547275.
|
| TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
|
| // This test only makes sense when cross-site subframes use separate
|
| // processes.
|
| @@ -2556,20 +2570,6 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
|
| root->render_manager()->GetRenderFrameProxyHost(host3->GetSiteInstance());
|
| EXPECT_TRUE(proxyC);
|
|
|
| - // Helper to check that the provided RenderProcessHost received exactly one
|
| - // page focus message with the provided focus and routing ID values.
|
| - auto verify_focus_message = [](MockRenderProcessHost* rph,
|
| - bool expected_focus,
|
| - int expected_routing_id) {
|
| - const IPC::Message* message =
|
| - rph->sink().GetUniqueMessageMatching(InputMsg_SetFocus::ID);
|
| - EXPECT_TRUE(message);
|
| - EXPECT_EQ(expected_routing_id, message->routing_id());
|
| - InputMsg_SetFocus::Param params;
|
| - EXPECT_TRUE(InputMsg_SetFocus::Read(message, ¶ms));
|
| - EXPECT_EQ(expected_focus, base::get<0>(params));
|
| - };
|
| -
|
| // Focus the main page, and verify that the focus message was sent to all
|
| // processes. The message to A should be sent through the main frame's
|
| // RenderViewHost, and the message to B and C should be send through proxies
|
| @@ -2578,10 +2578,10 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
|
| host1->GetProcess()->sink().ClearMessages();
|
| host3->GetProcess()->sink().ClearMessages();
|
| main_test_rfh()->GetRenderWidgetHost()->Focus();
|
| - verify_focus_message(main_test_rfh()->GetProcess(), true,
|
| - main_test_rfh()->GetRenderViewHost()->GetRoutingID());
|
| - verify_focus_message(host1->GetProcess(), true, proxyB->GetRoutingID());
|
| - verify_focus_message(host3->GetProcess(), true, proxyC->GetRoutingID());
|
| + VerifyPageFocusMessage(main_test_rfh()->GetProcess(), true,
|
| + main_test_rfh()->GetRenderViewHost()->GetRoutingID());
|
| + VerifyPageFocusMessage(host1->GetProcess(), true, proxyB->GetRoutingID());
|
| + VerifyPageFocusMessage(host3->GetProcess(), true, proxyC->GetRoutingID());
|
|
|
| // Similarly, simulate focus loss on main page, and verify that the focus
|
| // message was sent to all processes.
|
| @@ -2589,10 +2589,70 @@ TEST_F(RenderFrameHostManagerTest, PageFocusPropagatesToSubframeProcesses) {
|
| host1->GetProcess()->sink().ClearMessages();
|
| host3->GetProcess()->sink().ClearMessages();
|
| main_test_rfh()->GetRenderWidgetHost()->Blur();
|
| - verify_focus_message(main_test_rfh()->GetProcess(), false,
|
| - main_test_rfh()->GetRenderViewHost()->GetRoutingID());
|
| - verify_focus_message(host1->GetProcess(), false, proxyB->GetRoutingID());
|
| - verify_focus_message(host3->GetProcess(), false, proxyC->GetRoutingID());
|
| + VerifyPageFocusMessage(main_test_rfh()->GetProcess(), false,
|
| + main_test_rfh()->GetRenderViewHost()->GetRoutingID());
|
| + VerifyPageFocusMessage(host1->GetProcess(), false, proxyB->GetRoutingID());
|
| + VerifyPageFocusMessage(host3->GetProcess(), false, proxyC->GetRoutingID());
|
| +}
|
| +
|
| +// Check that page-level focus state is preserved across subframe navigations.
|
| +//
|
| +// TODO(alexmos): Move this test to FrameTree unit tests once NavigateToEntry
|
| +// is moved to a common place. See https://crbug.com/547275.
|
| +TEST_F(RenderFrameHostManagerTest,
|
| + PageFocusIsPreservedAcrossSubframeNavigations) {
|
| + // This test only makes sense when cross-site subframes use separate
|
| + // processes.
|
| + if (!AreAllSitesIsolatedForTesting())
|
| + return;
|
| +
|
| + const GURL kUrlA("http://a.com/");
|
| + const GURL kUrlB("http://b.com/");
|
| + const GURL kUrlC("http://c.com/");
|
| +
|
| + // Set up a page at a.com with a b.com subframe.
|
| + contents()->NavigateAndCommit(kUrlA);
|
| + main_test_rfh()->OnCreateChildFrame(
|
| + main_test_rfh()->GetProcess()->GetNextRoutingID(),
|
| + blink::WebTreeScopeType::Document, "frame1",
|
| + blink::WebSandboxFlags::None);
|
| +
|
| + FrameTreeNode* root = contents()->GetFrameTree()->root();
|
| + RenderFrameHostManager* child = root->child_at(0)->render_manager();
|
| +
|
| + // Navigate subframe to B.
|
| + NavigationEntryImpl entryB(nullptr /* instance */, -1 /* page_id */, kUrlB,
|
| + Referrer(kUrlA, blink::WebReferrerPolicyDefault),
|
| + base::string16() /* title */,
|
| + ui::PAGE_TRANSITION_LINK,
|
| + false /* is_renderer_init */);
|
| + TestRenderFrameHost* hostB =
|
| + static_cast<TestRenderFrameHost*>(NavigateToEntry(child, entryB));
|
| + child->DidNavigateFrame(hostB, true);
|
| +
|
| + // Ensure that the main page is focused.
|
| + main_test_rfh()->GetView()->Focus();
|
| + EXPECT_TRUE(main_test_rfh()->GetView()->HasFocus());
|
| +
|
| + // Navigate the subframe to C.
|
| + NavigationEntryImpl entryC(nullptr /* instance */, -1 /* page_id */, kUrlC,
|
| + Referrer(kUrlA, blink::WebReferrerPolicyDefault),
|
| + base::string16() /* title */,
|
| + ui::PAGE_TRANSITION_LINK,
|
| + false /* is_renderer_init */);
|
| + TestRenderFrameHost* hostC =
|
| + static_cast<TestRenderFrameHost*>(NavigateToEntry(child, entryC));
|
| + child->DidNavigateFrame(hostC, true);
|
| +
|
| + // The main frame should now have a proxy for C.
|
| + RenderFrameProxyHost* proxy =
|
| + root->render_manager()->GetRenderFrameProxyHost(hostC->GetSiteInstance());
|
| + EXPECT_TRUE(proxy);
|
| +
|
| + // Since the B->C navigation happened while the current page was focused,
|
| + // page focus should propagate to the new subframe process. Check that
|
| + // process C received the proper focus message.
|
| + VerifyPageFocusMessage(hostC->GetProcess(), true, proxy->GetRoutingID());
|
| }
|
|
|
| } // namespace content
|
|
|