Index: content/browser/site_per_process_browsertest.cc |
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc |
index 5a2be34f0dd18e0ce3d25af42cde83012e0863c7..bd1d08827ff0e003a8904af9f614afa16f09cab1 100644 |
--- a/content/browser/site_per_process_browsertest.cc |
+++ b/content/browser/site_per_process_browsertest.cc |
@@ -31,6 +31,7 @@ |
#include "content/browser/renderer_host/render_view_host_impl.h" |
#include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
#include "content/browser/renderer_host/render_widget_host_view_aura.h" |
+#include "content/browser/web_contents/web_contents_impl.h" |
#include "content/common/frame_messages.h" |
#include "content/common/input/synthetic_tap_gesture_params.h" |
#include "content/common/view_messages.h" |
@@ -46,6 +47,7 @@ |
#include "content/public/test/content_browser_test_utils.h" |
#include "content/public/test/test_navigation_observer.h" |
#include "content/public/test/test_utils.h" |
+#include "content/shell/browser/shell.h" |
#include "content/test/content_browser_test_utils_internal.h" |
#include "content/test/test_frame_navigation_observer.h" |
#include "ipc/ipc_security_test_util.h" |
@@ -6236,226 +6238,4 @@ IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
EXPECT_FALSE(rvh->is_swapped_out_); |
} |
-// This class will sniff incoming IPC for ViewHostMsg_TextInputStateChanged. |
-class TextInputStateChangedMessageFilter : public BrowserMessageFilter { |
- public: |
- explicit TextInputStateChangedMessageFilter( |
- RenderWidgetHostImpl* render_widget_host) |
- : BrowserMessageFilter(ViewMsgStart), text_input_state_changed_(false) { |
- if (!render_widget_host || !render_widget_host->GetProcess()) |
- text_input_state_changed_ = true; |
- old_state = *render_widget_host->GetView()->text_input_state(); |
- render_widget_host->GetProcess()->AddFilter(this); |
- } |
- |
- void WaitUntilTextInputStateChanges() { |
- if (!text_input_state_changed_) { |
- message_loop_runner_ = new MessageLoopRunner; |
- message_loop_runner_->Run(); |
- } |
- } |
- |
- private: |
- ~TextInputStateChangedMessageFilter() override {} |
- |
- bool OnMessageReceived(const IPC::Message& msg) override { |
- IPC_BEGIN_MESSAGE_MAP(TextInputStateChangedMessageFilter, msg) |
- IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputStateChanged, |
- OnTextInputStateChangedMessageReceived) |
- IPC_END_MESSAGE_MAP() |
- return false; |
- } |
- |
- void OnTextInputStateChangedMessageReceived(const TextInputState& new_state) { |
- if (new_state.type != old_state.type || new_state.mode != old_state.mode || |
- new_state.value != old_state.value) { |
- text_input_state_changed_ = true; |
- if (message_loop_runner_) |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
- message_loop_runner_->QuitClosure()); |
- } |
- } |
- |
- bool text_input_state_changed_; |
- scoped_refptr<MessageLoopRunner> message_loop_runner_; |
- TextInputState old_state; |
- |
- DISALLOW_COPY_AND_ASSIGN(TextInputStateChangedMessageFilter); |
-}; |
- |
-// Verify that when moving the focus between different frames, the WebContents |
-// properly keeps track of the text input state. |
-// The test loads a page with one input field, two out of process frames, and a |
-// second input field positioned after the last <iframe>. Then a sequence of TAB |
-// inputs are faked to navigate focus in between the different <input> elements. |
-// After each change, we check with the RWHV of the frame as well as the |
-// WebContents to make sure the text input state is as expected. |
-IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, TextInputStateChanged) { |
- GURL main_page_url(embedded_test_server()->GetURL( |
- "a.com", "/textinput/page_with_input_iframeX2_input.html")); |
- NavigateToURL(shell(), main_page_url); |
- |
- WebContents* contents = shell()->web_contents(); |
- |
- FrameTreeNode* root = web_contents()->GetFrameTree()->root(); |
- |
- FrameTreeNode* child_b = root->child_at(0); |
- GURL child_b_url(embedded_test_server()->GetURL( |
- "b.com", "/textinput/page_with_input.html")); |
- NavigateFrameToURL(child_b, child_b_url); |
- EXPECT_TRUE(WaitForRenderFrameReady(child_b->current_frame_host())); |
- |
- FrameTreeNode* child_c = root->child_at(1); |
- GURL child_c_url(embedded_test_server()->GetURL( |
- "c.com", "/textinput/page_with_input.html")); |
- NavigateFrameToURL(child_c, child_c_url); |
- EXPECT_TRUE(WaitForRenderFrameReady(child_c->current_frame_host())); |
- |
- RenderWidgetHostImpl* root_rwh = |
- root->current_frame_host()->GetRenderWidgetHost(); |
- RenderWidgetHostViewBase* root_rwhv = root_rwh->GetView(); |
- |
- RenderWidgetHostImpl* child_b_rwh = |
- child_b->current_frame_host()->GetRenderWidgetHost(); |
- RenderWidgetHostViewBase* child_b_rwhv = child_b_rwh->GetView(); |
- |
- RenderWidgetHostImpl* child_c_rwh = |
- child_c->current_frame_host()->GetRenderWidgetHost(); |
- RenderWidgetHostViewBase* child_c_rwhv = child_c_rwh->GetView(); |
- |
- // Change the text value in <input> field of either frame so that we can |
- // later track the changes. |
- EXPECT_TRUE( |
- ExecuteScript(child_b->current_frame_host(), |
- "document.querySelector('input').value = 'second';")); |
- EXPECT_TRUE( |
- ExecuteScript(child_c->current_frame_host(), |
- "document.querySelector('input').value = 'third';")); |
- |
- // Verify the input type is none in the beginning. |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, root_rwhv->text_input_state()->type); |
- |
- // A helper function to send a tab key to the frame and wait for a state |
- // changed message. |
- auto press_tab_and_wait_for_text_input_state_change = |
- [contents](RenderWidgetHostImpl* rwh) { |
- scoped_refptr<TextInputStateChangedMessageFilter> filter = |
- new TextInputStateChangedMessageFilter(rwh); |
- SimulateKeyPress(contents, ui::VKEY_TAB, false, false, false, false); |
- filter->WaitUntilTextInputStateChanges(); |
- }; |
- |
- // Send focus to the first input field. |
- press_tab_and_wait_for_text_input_state_change(root_rwh); |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, root_rwhv->text_input_state()->type); |
- EXPECT_EQ("first", root_rwhv->text_input_state()->value); |
- |
- // Verify the top-level state is changed. |
- EXPECT_EQ("first", web_contents()->GetTextInputState()->value); |
- |
- // Send focus to the input field in frame b. |
- press_tab_and_wait_for_text_input_state_change(child_b_rwh); |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, child_b_rwhv->text_input_state()->type); |
- EXPECT_EQ("second", child_b_rwhv->text_input_state()->value); |
- |
- EXPECT_EQ("second", web_contents()->GetTextInputState()->value); |
- |
- // Send focus to the input field in frame c. |
- press_tab_and_wait_for_text_input_state_change(child_c_rwh); |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, child_c_rwhv->text_input_state()->type); |
- EXPECT_EQ("third", child_c_rwhv->text_input_state()->value); |
- |
- EXPECT_EQ("third", web_contents()->GetTextInputState()->value); |
- |
- // Send focus to the last input field in top frame. |
- press_tab_and_wait_for_text_input_state_change(root_rwh); |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, root_rwhv->text_input_state()->type); |
- EXPECT_EQ("fourth", root_rwhv->text_input_state()->value); |
- |
- EXPECT_EQ("fourth", web_contents()->GetTextInputState()->value); |
-} |
- |
-// Disable this test on Android (http://crbug.com/603209) |
-#if defined(OS_ANDROID) |
-#define MAYBE_TextInputStateChangesAfterRendererCrashes \ |
- DISABLED_TextInputStateChangesAfterRendererCrashes |
-#else |
-#define MAYBE_TextInputStateChangesAfterRendererCrashes \ |
- TextInputStateChangesAfterRendererCrashes |
-#endif |
- |
-IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, |
- MAYBE_TextInputStateChangesAfterRendererCrashes) { |
- GURL main_url( |
- embedded_test_server()->GetURL("a.com", "/page_with_iframe.html")); |
- NavigateToURL(shell(), main_url); |
- WebContentsImpl* contents = web_contents(); |
- |
- FrameTreeNode* root = contents->GetFrameTree()->root(); |
- |
- FrameTreeNode* child = root->child_at(0); |
- GURL child_url(embedded_test_server()->GetURL( |
- "b.com", "/textinput/page_with_input.html")); |
- NavigateFrameToURL(child, child_url); |
- EXPECT_TRUE(WaitForRenderFrameReady(child->current_frame_host())); |
- |
- // Verify that the text input state is initially none. |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, contents->GetTextInputState()->type); |
- |
- auto press_tab_and_wait_for_state_change = |
- [contents](RenderWidgetHostImpl* rwh) { |
- scoped_refptr<TextInputStateChangedMessageFilter> filter = |
- new TextInputStateChangedMessageFilter(rwh); |
- SimulateKeyPress(contents, ui::VKEY_TAB, false, false, false, false); |
- filter->WaitUntilTextInputStateChanges(); |
- }; |
- |
- auto crash_renderer_and_wait_for_input_state_none = [contents]( |
- RenderProcessHost* host) { |
- RenderProcessHostWatcher crash_observer( |
- host, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
- host->Shutdown(0, false); |
- crash_observer.Wait(); |
- |
- // We need to wait until the actual text input state update occurs. |
- while (contents->GetTextInputState()->type != ui::TEXT_INPUT_TYPE_NONE) { |
- scoped_refptr<MessageLoopRunner> loop_runner_ = new MessageLoopRunner(); |
- BrowserThread::PostDelayedTask(BrowserThread::UI, FROM_HERE, |
- loop_runner_->QuitClosure(), |
- base::TimeDelta::FromMilliseconds(0LL)); |
- loop_runner_->Run(); |
- } |
- }; |
- |
- // Press a tab key to focus the <input> and verify that the top level |
- // WebContents sees it. |
- RenderWidgetHostImpl* child_rwh = |
- child->current_frame_host()->GetRenderWidgetHost(); |
- press_tab_and_wait_for_state_change(child_rwh); |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, contents->GetTextInputState()->type); |
- |
- // Crash the renderer and wait until WebContentsImpl has updates the |
- // state. |
- RenderProcessHost* child_process = child_rwh->GetProcess(); |
- crash_renderer_and_wait_for_input_state_none(child_process); |
- |
- // Now repeat the same test for the top level RWHV. |
- // First remove the <iframe> and append an <input> |
- EXPECT_TRUE(ExecuteScript(contents, |
- "var f = document.querySelector('iframe'); " |
- "f.parentNode.removeChild(f);")); |
- EXPECT_TRUE(ExecuteScript( |
- contents, "document.body.appendChild(document.createElement('input'));")); |
- |
- // Press tab to focus the <input> and observe the state change. |
- RenderWidgetHostImpl* root_rwh = |
- root->current_frame_host()->GetRenderWidgetHost(); |
- press_tab_and_wait_for_state_change(root_rwh); |
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, contents->GetTextInputState()->type); |
- |
- // Crash the tab renderer and observer the input state going back to none. |
- RenderProcessHost* host_process = root_rwh->GetProcess(); |
- crash_renderer_and_wait_for_input_state_none(host_process); |
-} |
- |
} // namespace content |