| 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
|
|
|