| Index: content/browser/tab_contents/render_view_host_manager_unittest.cc
|
| diff --git a/content/browser/tab_contents/render_view_host_manager_unittest.cc b/content/browser/tab_contents/render_view_host_manager_unittest.cc
|
| index b7f14634f7449ff9faa6feb0dc7b6086f75c3f5a..ddb5d1e6c5f2e51156190bbcb5e1ef0210339654 100644
|
| --- a/content/browser/tab_contents/render_view_host_manager_unittest.cc
|
| +++ b/content/browser/tab_contents/render_view_host_manager_unittest.cc
|
| @@ -2,6 +2,7 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "base/utf_string_conversions.h"
|
| #include "content/browser/browser_thread_impl.h"
|
| #include "content/browser/browser_url_handler.h"
|
| #include "content/browser/mock_content_browser_client.h"
|
| @@ -24,6 +25,7 @@
|
| #include "content/test/test_notification_tracker.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "googleurl/src/url_util.h"
|
| +#include "ui/base/javascript_message_type.h"
|
| #include "webkit/glue/webkit_glue.h"
|
|
|
| using content::BrowserThread;
|
| @@ -217,6 +219,82 @@ TEST_F(RenderViewHostManagerTest, NewTabPageProcesses) {
|
| contents2.GetRenderViewHost()->site_instance());
|
| }
|
|
|
| +// Ensure that the browser ignores most IPC messages that arrive from a
|
| +// RenderViewHost that has been swapped out. We do not want to take
|
| +// action on requests from a non-active renderer. The main exception is
|
| +// for synchronous messages, which cannot be ignored without leaving the
|
| +// renderer in a stuck state. See http://crbug.com/93427.
|
| +TEST_F(RenderViewHostManagerTest, FilterMessagesWhileSwappedOut) {
|
| + BrowserThreadImpl ui_thread(BrowserThread::UI, MessageLoop::current());
|
| + const GURL kNtpUrl(chrome::kTestNewTabURL);
|
| + const GURL kDestUrl("http://www.google.com/");
|
| +
|
| + // Navigate our first tab to the new tab page and then to the destination.
|
| + NavigateActiveAndCommit(kNtpUrl);
|
| + TestRenderViewHost* ntp_rvh = static_cast<TestRenderViewHost*>(
|
| + contents()->GetRenderManagerForTesting()->current_host());
|
| +
|
| + // Send an update title message and make sure it works.
|
| + const string16 ntp_title = ASCIIToUTF16("NTP Title");
|
| + WebKit::WebTextDirection direction = WebKit::WebTextDirectionLeftToRight;
|
| + EXPECT_TRUE(ntp_rvh->TestOnMessageReceived(
|
| + ViewHostMsg_UpdateTitle(rvh()->routing_id(), 0, ntp_title, direction)));
|
| + EXPECT_EQ(ntp_title, contents()->GetTitle());
|
| +
|
| + // Navigate to a cross-site URL.
|
| + contents()->GetController().LoadURL(
|
| + kDestUrl, content::Referrer(), content::PAGE_TRANSITION_LINK,
|
| + std::string());
|
| + EXPECT_TRUE(contents()->cross_navigation_pending());
|
| + TestRenderViewHost* dest_rvh = static_cast<TestRenderViewHost*>(
|
| + contents()->GetRenderManagerForTesting()->pending_render_view_host());
|
| + ASSERT_TRUE(dest_rvh);
|
| + EXPECT_NE(ntp_rvh, dest_rvh);
|
| +
|
| + // BeforeUnload finishes.
|
| + ntp_rvh->SendShouldCloseACK(true);
|
| +
|
| + // Assume SwapOutACK times out, so the dest_rvh proceeds and commits.
|
| + dest_rvh->SendNavigate(101, kDestUrl);
|
| +
|
| + // The new RVH should be able to update its title.
|
| + const string16 dest_title = ASCIIToUTF16("Google");
|
| + EXPECT_TRUE(dest_rvh->TestOnMessageReceived(
|
| + ViewHostMsg_UpdateTitle(rvh()->routing_id(), 101, dest_title,
|
| + direction)));
|
| + EXPECT_EQ(dest_title, contents()->GetTitle());
|
| +
|
| + // The old renderer, being slow, now updates the title. It should be filtered
|
| + // out and not take effect.
|
| + EXPECT_TRUE(ntp_rvh->is_swapped_out());
|
| + EXPECT_TRUE(ntp_rvh->TestOnMessageReceived(
|
| + ViewHostMsg_UpdateTitle(rvh()->routing_id(), 0, ntp_title, direction)));
|
| + EXPECT_EQ(dest_title, contents()->GetTitle());
|
| +
|
| + // We cannot filter out synchronous IPC messages, because the renderer would
|
| + // be left waiting for a reply. We pick RunBeforeUnloadConfirm as an example
|
| + // that can run easily within a unit test, and that needs to be suppressed
|
| + // but still receive a reply.
|
| + MockRenderProcessHost* ntp_process_host =
|
| + static_cast<MockRenderProcessHost*>(ntp_rvh->process());
|
| + ntp_process_host->sink().ClearMessages();
|
| + const string16 msg = ASCIIToUTF16("Message");
|
| + bool result = false;
|
| + string16 unused;
|
| + EXPECT_TRUE(ntp_rvh->TestOnMessageReceived(
|
| + ViewHostMsg_RunBeforeUnloadConfirm(rvh()->routing_id(), kNtpUrl, msg,
|
| + &result, &unused)));
|
| + EXPECT_TRUE(ntp_process_host->sink().GetUniqueMessageMatching(IPC_REPLY_ID));
|
| +
|
| + // Also test RunJavaScriptMessage.
|
| + ntp_process_host->sink().ClearMessages();
|
| + EXPECT_TRUE(ntp_rvh->TestOnMessageReceived(
|
| + ViewHostMsg_RunJavaScriptMessage(rvh()->routing_id(), msg, msg, kNtpUrl,
|
| + ui::JAVASCRIPT_MESSAGE_TYPE_CONFIRM,
|
| + &result, &unused)));
|
| + EXPECT_TRUE(ntp_process_host->sink().GetUniqueMessageMatching(IPC_REPLY_ID));
|
| +}
|
| +
|
| // When there is an error with the specified page, renderer exits view-source
|
| // mode. See WebFrameImpl::DidFail(). We check by this test that
|
| // EnableViewSourceMode message is sent on every navigation regardless
|
|
|