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 <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 DCHECK(source == web_contents_); | 268 DCHECK(source == web_contents_); |
269 | 269 |
270 std::string ascii_message = base::UTF16ToASCII(message); | 270 std::string ascii_message = base::UTF16ToASCII(message); |
271 if (base::MatchPattern(ascii_message, filter_)) { | 271 if (base::MatchPattern(ascii_message, filter_)) { |
272 message_ = ascii_message; | 272 message_ = ascii_message; |
273 message_loop_runner_->Quit(); | 273 message_loop_runner_->Quit(); |
274 } | 274 } |
275 return false; | 275 return false; |
276 } | 276 } |
277 | 277 |
| 278 // A BrowserMessageFilter that drops SwapOut ACK messages. |
| 279 class SwapoutACKMessageFilter : public BrowserMessageFilter { |
| 280 public: |
| 281 SwapoutACKMessageFilter() : BrowserMessageFilter(FrameMsgStart) {} |
| 282 |
| 283 protected: |
| 284 ~SwapoutACKMessageFilter() override {} |
| 285 |
| 286 private: |
| 287 // BrowserMessageFilter: |
| 288 bool OnMessageReceived(const IPC::Message& message) override { |
| 289 return message.type() == FrameHostMsg_SwapOut_ACK::ID; |
| 290 } |
| 291 |
| 292 DISALLOW_COPY_AND_ASSIGN(SwapoutACKMessageFilter); |
| 293 }; |
| 294 |
278 } // namespace | 295 } // namespace |
279 | 296 |
280 // | 297 // |
281 // SitePerProcessBrowserTest | 298 // SitePerProcessBrowserTest |
282 // | 299 // |
283 | 300 |
284 SitePerProcessBrowserTest::SitePerProcessBrowserTest() { | 301 SitePerProcessBrowserTest::SitePerProcessBrowserTest() { |
285 }; | 302 }; |
286 | 303 |
287 std::string SitePerProcessBrowserTest::DepictFrameTree(FrameTreeNode* node) { | 304 std::string SitePerProcessBrowserTest::DepictFrameTree(FrameTreeNode* node) { |
(...skipping 3076 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3364 TitleWatcher title_watcher(shell()->web_contents(), expected_title); | 3381 TitleWatcher title_watcher(shell()->web_contents(), expected_title); |
3365 EXPECT_TRUE(ExecuteScriptAndExtractBool( | 3382 EXPECT_TRUE(ExecuteScriptAndExtractBool( |
3366 popup_root->child_at(0)->current_frame_host(), | 3383 popup_root->child_at(0)->current_frame_host(), |
3367 "window.domAutomationController.send(" | 3384 "window.domAutomationController.send(" |
3368 " postToOpenerOfSibling('subframe2', 'msg', '*'));", | 3385 " postToOpenerOfSibling('subframe2', 'msg', '*'));", |
3369 &success)); | 3386 &success)); |
3370 EXPECT_TRUE(success); | 3387 EXPECT_TRUE(success); |
3371 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); | 3388 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); |
3372 } | 3389 } |
3373 | 3390 |
| 3391 // Test for https://crbug.com/515302. Perform two navigations, A->B->A, and |
| 3392 // delay the SwapOut ACK from the A->B navigation, so that the second B->A |
| 3393 // navigation is initiated before the first page receives the SwapOut ACK. |
| 3394 // Ensure that the RVH(A) that's pending deletion is not reused in that case. |
| 3395 IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
| 3396 RenderViewHostPendingDeletionIsNotReused) { |
| 3397 GURL a_url(embedded_test_server()->GetURL("a.com", "/title1.html")); |
| 3398 NavigateToURL(shell(), a_url); |
| 3399 |
| 3400 FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
| 3401 ->GetFrameTree() |
| 3402 ->root(); |
| 3403 RenderFrameHostImpl* rfh = root->current_frame_host(); |
| 3404 RenderViewHostImpl* rvh = rfh->render_view_host(); |
| 3405 RenderFrameDeletedObserver deleted_observer(rfh); |
| 3406 |
| 3407 // Install a BrowserMessageFilter to drop SwapOut ACK messages in A's |
| 3408 // process. |
| 3409 scoped_refptr<SwapoutACKMessageFilter> filter = new SwapoutACKMessageFilter(); |
| 3410 rfh->GetProcess()->AddFilter(filter.get()); |
| 3411 |
| 3412 // Navigate to B. This must wait for DidCommitProvisionalLoad, as opposed to |
| 3413 // DidStopLoading, since otherwise the SwapOut timer might call OnSwappedOut |
| 3414 // and destroy |rvh| before its pending deletion status is checked. |
| 3415 GURL b_url(embedded_test_server()->GetURL("b.com", "/title2.html")); |
| 3416 TestFrameNavigationObserver commit_observer(root); |
| 3417 shell()->LoadURL(b_url); |
| 3418 commit_observer.Wait(); |
| 3419 |
| 3420 // Since the SwapOut ACK for A->B is dropped, the first page's |
| 3421 // RenderFrameHost and RenderViewHost should be pending deletion after the |
| 3422 // last navigation. |
| 3423 EXPECT_TRUE(root->render_manager()->IsPendingDeletion(rfh)); |
| 3424 EXPECT_TRUE(rvh->is_pending_deletion()); |
| 3425 |
| 3426 // Wait for process A to exit so we can reinitialize it cleanly for the next |
| 3427 // navigation. This can be removed once https://crbug.com/535246 is fixed. |
| 3428 RenderProcessHostWatcher process_exit_observer( |
| 3429 rvh->GetProcess(), |
| 3430 RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
| 3431 process_exit_observer.Wait(); |
| 3432 |
| 3433 // Start a navigation back to A and check that the RenderViewHost wasn't |
| 3434 // reused. |
| 3435 TestNavigationObserver navigation_observer(shell()->web_contents()); |
| 3436 shell()->LoadURL(a_url); |
| 3437 RenderViewHostImpl* pending_rvh = |
| 3438 root->render_manager()->pending_render_view_host(); |
| 3439 EXPECT_EQ(rvh->GetSiteInstance(), pending_rvh->GetSiteInstance()); |
| 3440 EXPECT_NE(rvh, pending_rvh); |
| 3441 |
| 3442 // Simulate that the dropped SwapOut ACK message arrives now on the original |
| 3443 // RenderFrameHost, which should now get deleted. |
| 3444 rfh->OnSwappedOut(); |
| 3445 EXPECT_TRUE(deleted_observer.deleted()); |
| 3446 |
| 3447 // Make sure the last navigation finishes without crashing. |
| 3448 navigation_observer.Wait(); |
| 3449 } |
| 3450 |
3374 } // namespace content | 3451 } // namespace content |
OLD | NEW |