OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/site_per_process_browsertest.h" | 5 #include "content/browser/site_per_process_browsertest.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 7904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7915 | 7915 |
7916 // Now go forward three entries from the child1 frame and check that the | 7916 // Now go forward three entries from the child1 frame and check that the |
7917 // history length and offset are not stale in b.com. | 7917 // history length and offset are not stale in b.com. |
7918 EXPECT_TRUE(ExecuteScript(child1, "history.go(3);")); | 7918 EXPECT_TRUE(ExecuteScript(child1, "history.go(3);")); |
7919 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); | 7919 EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
7920 EXPECT_EQ(main_url, root->current_url()); | 7920 EXPECT_EQ(main_url, root->current_url()); |
7921 EXPECT_EQ(child1_last_url, child1->current_url()); | 7921 EXPECT_EQ(child1_last_url, child1->current_url()); |
7922 EXPECT_EQ(child2_last_url, child2->current_url()); | 7922 EXPECT_EQ(child2_last_url, child2->current_url()); |
7923 } | 7923 } |
7924 | 7924 |
| 7925 // A BrowserMessageFilter that drops FrameHostMsg_OnDispatchLoad messages. |
| 7926 class DispatchLoadMessageFilter : public BrowserMessageFilter { |
| 7927 public: |
| 7928 DispatchLoadMessageFilter() : BrowserMessageFilter(FrameMsgStart) {} |
| 7929 |
| 7930 protected: |
| 7931 ~DispatchLoadMessageFilter() override {} |
| 7932 |
| 7933 private: |
| 7934 // BrowserMessageFilter: |
| 7935 bool OnMessageReceived(const IPC::Message& message) override { |
| 7936 return message.type() == FrameHostMsg_DispatchLoad::ID; |
| 7937 } |
| 7938 |
| 7939 DISALLOW_COPY_AND_ASSIGN(DispatchLoadMessageFilter); |
| 7940 }; |
| 7941 |
| 7942 // Test that the renderer isn't killed when a frame generates a load event just |
| 7943 // after becoming pending deletion. See https://crbug.com/636513. |
| 7944 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 7945 LoadEventForwardingWhilePendingDeletion) { |
| 7946 GURL main_url(embedded_test_server()->GetURL( |
| 7947 "a.com", "/cross_site_iframe_factory.html?a(a)")); |
| 7948 EXPECT_TRUE(NavigateToURL(shell(), main_url)); |
| 7949 FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
| 7950 FrameTreeNode* child = root->child_at(0); |
| 7951 |
| 7952 // Open a popup in the b.com process for later use. |
| 7953 GURL popup_url(embedded_test_server()->GetURL("b.com", "/title1.html")); |
| 7954 Shell* popup_shell = OpenPopup(root, popup_url, "foo"); |
| 7955 EXPECT_TRUE(popup_shell); |
| 7956 |
| 7957 // Install a filter to drop DispatchLoad messages from b.com. |
| 7958 scoped_refptr<DispatchLoadMessageFilter> filter = |
| 7959 new DispatchLoadMessageFilter(); |
| 7960 RenderProcessHost* b_process = |
| 7961 popup_shell->web_contents()->GetMainFrame()->GetProcess(); |
| 7962 b_process->AddFilter(filter.get()); |
| 7963 |
| 7964 // Navigate subframe to b.com. Wait for commit but not full load. |
| 7965 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); |
| 7966 { |
| 7967 TestFrameNavigationObserver commit_observer(child); |
| 7968 EXPECT_TRUE( |
| 7969 ExecuteScript(child, "location.href = '" + b_url.spec() + "';")); |
| 7970 commit_observer.WaitForCommit(); |
| 7971 } |
| 7972 RenderFrameHostImpl* child_rfh = child->current_frame_host(); |
| 7973 child_rfh->DisableSwapOutTimerForTesting(); |
| 7974 |
| 7975 // At this point, the subframe should have a proxy in its parent's |
| 7976 // SiteInstance, a.com. |
| 7977 EXPECT_TRUE(child->render_manager()->GetProxyToParent()); |
| 7978 |
| 7979 // Now, go back to a.com in the subframe and wait for commit. |
| 7980 { |
| 7981 TestFrameNavigationObserver commit_observer(child); |
| 7982 web_contents()->GetController().GoBack(); |
| 7983 commit_observer.WaitForCommit(); |
| 7984 } |
| 7985 |
| 7986 // At this point, the subframe's old RFH for b.com should be pending |
| 7987 // deletion, and the subframe's proxy in a.com should've been cleared. |
| 7988 EXPECT_FALSE(child_rfh->is_active()); |
| 7989 EXPECT_FALSE(child->render_manager()->GetProxyToParent()); |
| 7990 |
| 7991 // Simulate that the load event is dispatched from |child_rfh| just after |
| 7992 // it's become pending deletion. |
| 7993 child_rfh->OnDispatchLoad(); |
| 7994 |
| 7995 // In the bug, OnDispatchLoad killed the b.com renderer. Ensure that this is |
| 7996 // not the case. Note that the process kill doesn't happen immediately, so |
| 7997 // IsRenderFrameLive() can't be checked here (yet). Instead, check that |
| 7998 // JavaScript can still execute in b.com using the popup. |
| 7999 EXPECT_TRUE(ExecuteScript(popup_shell->web_contents(), "true")); |
| 8000 } |
| 8001 |
7925 } // namespace content | 8002 } // namespace content |
OLD | NEW |