summaryrefslogtreecommitdiff
path: root/chromium/content/renderer/render_view_browsertest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/render_view_browsertest.cc')
-rw-r--r--chromium/content/renderer/render_view_browsertest.cc669
1 files changed, 450 insertions, 219 deletions
diff --git a/chromium/content/renderer/render_view_browsertest.cc b/chromium/content/renderer/render_view_browsertest.cc
index d6f4b3560ae..17a6f4e8da8 100644
--- a/chromium/content/renderer/render_view_browsertest.cc
+++ b/chromium/content/renderer/render_view_browsertest.cc
@@ -18,7 +18,6 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/gmock_callback_support.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -43,6 +42,7 @@
#include "content/public/common/use_zoom_for_dsf_policy.h"
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/fake_render_widget_host.h"
#include "content/public/test/frame_load_waiter.h"
#include "content/public/test/local_frame_host_interceptor.h"
#include "content/public/test/render_view_test.h"
@@ -63,6 +63,7 @@
#include "content/test/mock_keyboard.h"
#include "content/test/test_render_frame.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/mojom/base/text_direction.mojom-blink.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_status_flags.h"
#include "net/dns/public/resolve_error_info.h"
@@ -99,6 +100,7 @@
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_window_features.h"
#include "ui/accessibility/ax_mode.h"
+#include "ui/base/ime/mojom/text_input_state.mojom.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/event.h"
#include "ui/events/keycodes/dom/dom_code.h"
@@ -132,6 +134,10 @@
#include "ui/events/keycodes/keyboard_code_conversion.h"
#endif
+#if defined(USE_X11) && defined(USE_OZONE)
+#include "ui/base/ui_base_features.h"
+#endif
+
using base::TimeDelta;
using blink::WebFrame;
using blink::WebFrameContentDumper;
@@ -256,6 +262,14 @@ class RenderViewImplTest : public RenderViewTest {
return static_cast<TestRenderFrame*>(view()->GetMainRenderFrame());
}
+ blink::mojom::FrameWidgetInputHandler* GetFrameWidgetInputHandler() {
+ return render_widget_host_->GetFrameWidgetInputHandler();
+ }
+
+ blink::mojom::WidgetInputHandler* GetWidgetInputHandler() {
+ return render_widget_host_->GetWidgetInputHandler();
+ }
+
RenderAccessibilityManager* GetRenderAccessibilityManager() {
return frame()->GetRenderAccessibilityManager();
}
@@ -264,6 +278,13 @@ class RenderViewImplTest : public RenderViewTest {
return GetRenderAccessibilityManager()->GetAccessibilityMode();
}
+ const std::vector<gfx::Rect>& LastCompositionBounds() {
+ render_widget_host_->GetWidgetInputHandler()->RequestCompositionUpdates(
+ true, false);
+ base::RunLoop().RunUntilIdle();
+ return render_widget_host_->LastCompositionBounds();
+ }
+
void ReceiveDisableDeviceEmulation(RenderViewImpl* view) {
// Emulates receiving an IPC message.
RenderWidget* widget =
@@ -280,12 +301,6 @@ class RenderViewImplTest : public RenderViewTest {
widget->OnEnableDeviceEmulation(params);
}
- void ReceiveSetTextDirection(RenderWidget* widget,
- base::i18n::TextDirection direction) {
- // Emulates receiving an IPC message.
- widget->OnSetTextDirection(direction);
- }
-
void GoToOffsetWithParams(int offset,
const PageState& state,
mojom::CommonNavigationParamsPtr common_params,
@@ -317,47 +332,11 @@ class RenderViewImplTest : public RenderViewTest {
return param;
}
- // Sends IPC messages that emulates a key-press event.
- int SendKeyEvent(MockKeyboard::Layout layout,
- int key_code,
- MockKeyboard::Modifiers modifiers,
- base::string16* output) {
-#if defined(OS_WIN)
- // Retrieve the Unicode character for the given tuple (keyboard-layout,
- // key-code, and modifiers).
- // Exit when a keyboard-layout driver cannot assign a Unicode character to
- // the tuple to prevent sending an invalid key code to the RenderView
- // object.
- CHECK(mock_keyboard_.get());
- CHECK(output);
- int length = mock_keyboard_->GetCharacters(layout, key_code, modifiers,
- output);
- if (length != 1)
- return -1;
-
- // Create IPC messages from Windows messages and send them to our
- // back-end.
- // A keyboard event of Windows consists of three Windows messages:
- // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
- // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
- // WM_CHAR sends a composed Unicode character.
- MSG msg1 = { NULL, WM_KEYDOWN, key_code, 0 };
- ui::KeyEvent evt1(msg1);
- NativeWebKeyboardEvent keydown_event(evt1);
- SendNativeKeyEvent(keydown_event);
-
- MSG msg2 = { NULL, WM_CHAR, (*output)[0], 0 };
- ui::KeyEvent evt2(msg2);
- NativeWebKeyboardEvent char_event(evt2);
- SendNativeKeyEvent(char_event);
-
- MSG msg3 = { NULL, WM_KEYUP, key_code, 0 };
- ui::KeyEvent evt3(msg3);
- NativeWebKeyboardEvent keyup_event(evt3);
- SendNativeKeyEvent(keyup_event);
-
- return length;
-#elif defined(USE_AURA) && defined(USE_X11)
+#if defined(USE_X11)
+ int SendKeyEventX11(MockKeyboard::Layout layout,
+ int key_code,
+ MockKeyboard::Modifiers modifiers,
+ base::string16* output) {
// We ignore |layout|, which means we are only testing the layout of the
// current locale. TODO(mazda): fix this to respect |layout|.
CHECK(output);
@@ -365,8 +344,7 @@ class RenderViewImplTest : public RenderViewTest {
ui::ScopedXI2Event xevent;
xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
- static_cast<ui::KeyboardCode>(key_code),
- flags);
+ static_cast<ui::KeyboardCode>(key_code), flags);
auto event1 = ui::BuildKeyEventFromXEvent(*xevent);
NativeWebKeyboardEvent keydown_event(*event1);
SendNativeKeyEvent(keydown_event);
@@ -374,8 +352,7 @@ class RenderViewImplTest : public RenderViewTest {
// X11 doesn't actually have native character events, but give the test
// what it wants.
xevent.InitKeyEvent(ui::ET_KEY_PRESSED,
- static_cast<ui::KeyboardCode>(key_code),
- flags);
+ static_cast<ui::KeyboardCode>(key_code), flags);
auto event2 = ui::BuildKeyEventFromXEvent(*xevent);
event2->set_character(
DomCodeToUsLayoutCharacter(event2->code(), event2->flags()));
@@ -385,8 +362,7 @@ class RenderViewImplTest : public RenderViewTest {
SendNativeKeyEvent(char_event);
xevent.InitKeyEvent(ui::ET_KEY_RELEASED,
- static_cast<ui::KeyboardCode>(key_code),
- flags);
+ static_cast<ui::KeyboardCode>(key_code), flags);
auto event3 = ui::BuildKeyEventFromXEvent(*xevent);
NativeWebKeyboardEvent keyup_event(*event3);
SendNativeKeyEvent(keyup_event);
@@ -396,12 +372,18 @@ class RenderViewImplTest : public RenderViewTest {
flags);
output->assign(1, static_cast<base::char16>(c));
return 1;
-#elif defined(USE_OZONE)
- const int flags = ConvertMockKeyboardModifier(modifiers);
+ }
+#endif
+
+#if defined(USE_OZONE)
+ int SendKeyEventOzone(MockKeyboard::Layout layout,
+ int key_code,
+ MockKeyboard::Modifiers modifiers,
+ base::string16* output) {
+ int flags = ConvertMockKeyboardModifier(modifiers);
ui::KeyEvent keydown_event(ui::ET_KEY_PRESSED,
- static_cast<ui::KeyboardCode>(key_code),
- flags);
+ static_cast<ui::KeyboardCode>(key_code), flags);
NativeWebKeyboardEvent keydown_web_event(keydown_event);
SendNativeKeyEvent(keydown_web_event);
@@ -412,8 +394,7 @@ class RenderViewImplTest : public RenderViewTest {
SendNativeKeyEvent(char_web_event);
ui::KeyEvent keyup_event(ui::ET_KEY_RELEASED,
- static_cast<ui::KeyboardCode>(key_code),
- flags);
+ static_cast<ui::KeyboardCode>(key_code), flags);
NativeWebKeyboardEvent keyup_web_event(keyup_event);
SendNativeKeyEvent(keyup_web_event);
@@ -422,6 +403,57 @@ class RenderViewImplTest : public RenderViewTest {
flags);
output->assign(1, static_cast<base::char16>(c));
return 1;
+ }
+#endif
+
+ // Sends IPC messages that emulates a key-press event.
+ int SendKeyEvent(MockKeyboard::Layout layout,
+ int key_code,
+ MockKeyboard::Modifiers modifiers,
+ base::string16* output) {
+#if defined(OS_WIN)
+ // Retrieve the Unicode character for the given tuple (keyboard-layout,
+ // key-code, and modifiers).
+ // Exit when a keyboard-layout driver cannot assign a Unicode character to
+ // the tuple to prevent sending an invalid key code to the RenderView
+ // object.
+ CHECK(mock_keyboard_.get());
+ CHECK(output);
+ int length =
+ mock_keyboard_->GetCharacters(layout, key_code, modifiers, output);
+ if (length != 1)
+ return -1;
+
+ // Create IPC messages from Windows messages and send them to our
+ // back-end.
+ // A keyboard event of Windows consists of three Windows messages:
+ // WM_KEYDOWN, WM_CHAR, and WM_KEYUP.
+ // WM_KEYDOWN and WM_KEYUP sends virtual-key codes. On the other hand,
+ // WM_CHAR sends a composed Unicode character.
+ MSG msg1 = {NULL, WM_KEYDOWN, key_code, 0};
+ ui::KeyEvent evt1(msg1);
+ NativeWebKeyboardEvent keydown_event(evt1);
+ SendNativeKeyEvent(keydown_event);
+
+ MSG msg2 = {NULL, WM_CHAR, (*output)[0], 0};
+ ui::KeyEvent evt2(msg2);
+ NativeWebKeyboardEvent char_event(evt2);
+ SendNativeKeyEvent(char_event);
+
+ MSG msg3 = {NULL, WM_KEYUP, key_code, 0};
+ ui::KeyEvent evt3(msg3);
+ NativeWebKeyboardEvent keyup_event(evt3);
+ SendNativeKeyEvent(keyup_event);
+
+ return length;
+#elif defined(USE_X11)
+#if defined(USE_OZONE)
+ if (features::IsUsingOzonePlatform())
+ return SendKeyEventOzone(layout, key_code, modifiers, output);
+#endif
+ return SendKeyEventX11(layout, key_code, modifiers, output);
+#elif defined(USE_OZONE)
+ return SendKeyEventOzone(layout, key_code, modifiers, output);
#else
NOTIMPLEMENTED();
return L'\0';
@@ -624,9 +656,7 @@ TEST_F(RenderViewImplTest, OnNavStateChanged) {
LoadHTML("<input type=\"text\" id=\"elt_text\"></input>");
// We should NOT have gotten a form state change notification yet.
- EXPECT_FALSE(render_thread_->sink().GetFirstMessageMatching(
- FrameHostMsg_UpdateState::ID));
- render_thread_->sink().ClearMessages();
+ EXPECT_FALSE(frame()->IsPageStateUpdated());
// Change the value of the input. We should have gotten an update state
// notification. We need to spin the message loop to catch this update.
@@ -634,8 +664,8 @@ TEST_F(RenderViewImplTest, OnNavStateChanged) {
"document.getElementById('elt_text').value = 'foo';");
base::RunLoop().RunUntilIdle();
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_UpdateState::ID));
+ // Check the page state is updated after the value of the input is changed.
+ EXPECT_TRUE(frame()->IsPageStateUpdated());
}
class RenderViewImplEmulatingPopupTest : public RenderViewImplTest {
@@ -941,8 +971,7 @@ TEST_F(RenderViewImplTest, BeginNavigation) {
blink::kWebNavigationPolicyCurrentTab;
render_thread_->sink().ClearMessages();
frame()->BeginNavigation(std::move(form_navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
// Popup links to WebUI URLs.
blink::WebURLRequest popup_request(GetWebUIURL("foo"));
@@ -962,8 +991,7 @@ TEST_F(RenderViewImplTest, BeginNavigation) {
blink::kWebNavigationPolicyNewForegroundTab;
render_thread_->sink().ClearMessages();
frame()->BeginNavigation(std::move(popup_navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
}
TEST_F(RenderViewImplTest, BeginNavigationHandlesAllTopLevel) {
@@ -992,8 +1020,7 @@ TEST_F(RenderViewImplTest, BeginNavigationHandlesAllTopLevel) {
render_thread_->sink().ClearMessages();
frame()->BeginNavigation(std::move(navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
}
}
@@ -1020,8 +1047,7 @@ TEST_F(RenderViewImplTest, BeginNavigationForWebUI) {
render_thread_->sink().ClearMessages();
frame()->BeginNavigation(std::move(navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
// Navigations to WebUI URLs.
auto webui_navigation_info = std::make_unique<blink::WebNavigationInfo>();
@@ -1040,8 +1066,7 @@ TEST_F(RenderViewImplTest, BeginNavigationForWebUI) {
blink::kWebNavigationPolicyCurrentTab;
render_thread_->sink().ClearMessages();
frame()->BeginNavigation(std::move(webui_navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
// Form posts to data URLs.
auto data_navigation_info = std::make_unique<blink::WebNavigationInfo>();
@@ -1067,8 +1092,7 @@ TEST_F(RenderViewImplTest, BeginNavigationForWebUI) {
blink::kWebNavigationPolicyCurrentTab;
render_thread_->sink().ClearMessages();
frame()->BeginNavigation(std::move(data_navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
// A popup that creates a view first and then navigates to a
// normal HTTP URL.
@@ -1094,8 +1118,7 @@ TEST_F(RenderViewImplTest, BeginNavigationForWebUI) {
render_thread_->sink().ClearMessages();
static_cast<RenderFrameImpl*>(new_view->GetMainRenderFrame())
->BeginNavigation(std::move(popup_navigation_info));
- EXPECT_TRUE(render_thread_->sink().GetUniqueMessageMatching(
- FrameHostMsg_OpenURL::ID));
+ EXPECT_TRUE(frame()->IsURLOpened());
}
// This test verifies that when device emulation is enabled, RenderFrameProxy
@@ -1248,7 +1271,7 @@ TEST_F(RenderViewImplEnableZoomForDSFTest,
RenderFrameImpl::CreateFrame(
routing_id, std::move(stub_interface_provider),
std::move(stub_browser_interface_broker), kProxyRoutingId,
- MSG_ROUTING_NONE, MSG_ROUTING_NONE, MSG_ROUTING_NONE,
+ base::UnguessableToken(), MSG_ROUTING_NONE, MSG_ROUTING_NONE,
base::UnguessableToken::Create(), base::UnguessableToken::Create(),
replication_state, compositor_deps_.get(), std::move(widget_params),
blink::mojom::FrameOwnerProperties::New(),
@@ -1316,7 +1339,7 @@ TEST_F(RenderViewImplTest, DetachingProxyAlsoDestroysProvisionalFrame) {
RenderFrameImpl::CreateFrame(
routing_id, std::move(stub_interface_provider),
std::move(stub_browser_interface_broker), kProxyRoutingId,
- MSG_ROUTING_NONE, frame()->GetRoutingID(), MSG_ROUTING_NONE,
+ base::UnguessableToken(), frame()->GetRoutingID(), MSG_ROUTING_NONE,
base::UnguessableToken::Create(), base::UnguessableToken::Create(),
replication_state, nullptr,
/*widget_params=*/nullptr, blink::mojom::FrameOwnerProperties::New(),
@@ -1360,9 +1383,43 @@ TEST_F(RenderViewImplEnableZoomForDSFTest,
EXPECT_TRUE(view()->GetWebView()->MainFrame()->IsWebRemoteFrame());
}
+class TextInputStateFakeRenderWidgetHost : public FakeRenderWidgetHost {
+ public:
+ void TextInputStateChanged(ui::mojom::TextInputStatePtr state) override {
+ updated_states_.push_back(std::move(state));
+ }
+
+ const std::vector<ui::mojom::TextInputStatePtr>& updated_states() {
+ return updated_states_;
+ }
+
+ void ClearState() { updated_states_.clear(); }
+
+ private:
+ std::vector<ui::mojom::TextInputStatePtr> updated_states_;
+};
+
+class RenderViewImplTextInputStateChanged : public RenderViewImplTest {
+ public:
+ std::unique_ptr<FakeRenderWidgetHost> CreateRenderWidgetHost() override {
+ return std::make_unique<TextInputStateFakeRenderWidgetHost>();
+ }
+
+ const std::vector<ui::mojom::TextInputStatePtr>& updated_states() {
+ return static_cast<TextInputStateFakeRenderWidgetHost*>(
+ render_widget_host_.get())
+ ->updated_states();
+ }
+
+ void ClearState() {
+ static_cast<TextInputStateFakeRenderWidgetHost*>(render_widget_host_.get())
+ ->ClearState();
+ }
+};
+
// Test that our IME backend sends a notification message when the input focus
// changes.
-TEST_F(RenderViewImplTest, OnImeTypeChanged) {
+TEST_F(RenderViewImplTextInputStateChanged, OnImeTypeChanged) {
// Load an HTML page consisting of two input fields.
LoadHTML(
"<html>"
@@ -1382,7 +1439,6 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
"<input id=\"test11\" type=\"text\" inputmode=\"unknown\"></input>"
"</body>"
"</html>");
- render_thread_->sink().ClearMessages();
struct InputModeTestCase {
const char* input_id;
@@ -1407,21 +1463,16 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
// activate IMEs.
ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
base::RunLoop().RunUntilIdle();
- render_thread_->sink().ClearMessages();
+ ClearState();
// Update the IME status and verify if our IME backend sends an IPC message
// to activate IMEs.
main_widget()->UpdateTextInputState();
- const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
- EXPECT_TRUE(msg != nullptr);
- EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID),
- msg->type());
- WidgetHostMsg_TextInputStateChanged::Param params;
- WidgetHostMsg_TextInputStateChanged::Read(msg, &params);
- TextInputState p = std::get<0>(params);
- ui::TextInputType type = p.type;
- ui::TextInputMode input_mode = p.mode;
- bool can_compose_inline = p.can_compose_inline;
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ ui::TextInputType type = updated_states()[0]->type;
+ ui::TextInputMode input_mode = updated_states()[0]->mode;
+ bool can_compose_inline = updated_states()[0]->can_compose_inline;
EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, type);
EXPECT_EQ(true, can_compose_inline);
@@ -1429,19 +1480,15 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
// de-activate IMEs.
ExecuteJavaScriptForTests("document.getElementById('test2').focus();");
base::RunLoop().RunUntilIdle();
- render_thread_->sink().ClearMessages();
+ ClearState();
// Update the IME status and verify if our IME backend sends an IPC message
// to de-activate IMEs.
main_widget()->UpdateTextInputState();
- msg = render_thread_->sink().GetMessageAt(0);
- EXPECT_TRUE(msg != nullptr);
- EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID),
- msg->type());
- WidgetHostMsg_TextInputStateChanged::Read(msg, &params);
- p = std::get<0>(params);
- type = p.type;
- input_mode = p.mode;
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ type = updated_states()[0]->type;
+ input_mode = updated_states()[0]->mode;
EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, type);
for (size_t i = 0; i < base::size(kInputModeTestCases); i++) {
@@ -1454,26 +1501,22 @@ TEST_F(RenderViewImplTest, OnImeTypeChanged) {
ExecuteJavaScriptAndReturnIntValue(base::ASCIIToUTF16(javascript),
nullptr);
base::RunLoop().RunUntilIdle();
- render_thread_->sink().ClearMessages();
+ ClearState();
// Update the IME status and verify if our IME backend sends an IPC
// message to activate IMEs.
main_widget()->UpdateTextInputState();
base::RunLoop().RunUntilIdle();
- const IPC::Message* msg = render_thread_->sink().GetMessageAt(0);
- EXPECT_TRUE(msg != nullptr);
- EXPECT_EQ(static_cast<uint32_t>(WidgetHostMsg_TextInputStateChanged::ID),
- msg->type());
- WidgetHostMsg_TextInputStateChanged::Read(msg, &params);
- p = std::get<0>(params);
- type = p.type;
- input_mode = p.mode;
+ EXPECT_EQ(1u, updated_states().size());
+ type = updated_states()[0]->type;
+ input_mode = updated_states()[0]->mode;
EXPECT_EQ(test_case->expected_mode, input_mode);
}
}
}
-TEST_F(RenderViewImplTest, ShouldSuppressKeyboardIsPropagated) {
+TEST_F(RenderViewImplTextInputStateChanged,
+ ShouldSuppressKeyboardIsPropagated) {
class TestAutofillClient : public blink::WebAutofillClient {
public:
TestAutofillClient() = default;
@@ -1508,25 +1551,27 @@ TEST_F(RenderViewImplTest, ShouldSuppressKeyboardIsPropagated) {
// Focus the text field, trigger a state update and check that the right IPC
// is sent.
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
- base::RunLoop().RunUntilIdle();
main_widget()->UpdateTextInputState();
- auto params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
- EXPECT_FALSE(std::get<0>(params).always_hide_ime);
- render_thread_->sink().ClearMessages();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_FALSE(updated_states()[0]->always_hide_ime);
+ ClearState();
// Tell the client to suppress the keyboard. Check whether always_hide_ime is
// set correctly.
client.SetShouldSuppressKeyboard(true);
main_widget()->UpdateTextInputState();
- params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
- EXPECT_TRUE(std::get<0>(params).always_hide_ime);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_TRUE(updated_states()[0]->always_hide_ime);
// Explicitly clean-up the autofill client, as otherwise a use-after-free
// happens.
GetMainFrame()->SetAutofillClient(nullptr);
}
-TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsAndInputPanelPolicy) {
+TEST_F(RenderViewImplTextInputStateChanged,
+ EditContextGetLayoutBoundsAndInputPanelPolicy) {
// Load an HTML page.
LoadHTML(
"<html>"
@@ -1535,7 +1580,7 @@ TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsAndInputPanelPolicy) {
"<body>"
"</body>"
"</html>");
- render_thread_->sink().ClearMessages();
+ ClearState();
// Create an EditContext with control and selection bounds and set input
// panel policy to auto.
ExecuteJavaScriptForTests(
@@ -1547,30 +1592,32 @@ TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsAndInputPanelPolicy) {
// This RunLoop is waiting for EditContext to be created and layout bounds
// to be updated in the EditContext.
base::RunLoop run_loop;
- base::PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
run_loop.Run();
// Update the IME status and verify if our IME backend sends an IPC message
// to notify layout bounds of the EditContext.
main_widget()->UpdateTextInputState();
- auto params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
- EXPECT_EQ(true, std::get<0>(params).show_ime_if_needed);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
blink::WebRect edit_context_control_bounds_expected(10, 20, 30, 40);
blink::WebRect edit_context_selection_bounds_expected(10, 20, 1, 5);
main_widget()->ConvertViewportToWindow(&edit_context_control_bounds_expected);
main_widget()->ConvertViewportToWindow(
&edit_context_selection_bounds_expected);
blink::WebRect actual_active_element_control_bounds(
- std::get<0>(params).edit_context_control_bounds.value());
+ updated_states()[0]->edit_context_control_bounds.value());
blink::WebRect actual_active_element_selection_bounds(
- std::get<0>(params).edit_context_selection_bounds.value());
+ updated_states()[0]->edit_context_selection_bounds.value());
EXPECT_EQ(edit_context_control_bounds_expected,
actual_active_element_control_bounds);
EXPECT_EQ(edit_context_selection_bounds_expected,
actual_active_element_selection_bounds);
}
-TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsWithFloatingValues) {
+TEST_F(RenderViewImplTextInputStateChanged,
+ EditContextGetLayoutBoundsWithFloatingValues) {
// Load an HTML page.
LoadHTML(
"<html>"
@@ -1579,7 +1626,7 @@ TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsWithFloatingValues) {
"<body>"
"</body>"
"</html>");
- render_thread_->sink().ClearMessages();
+ ClearState();
// Create an EditContext with control and selection bounds and set input
// panel policy to auto.
ExecuteJavaScriptForTests(
@@ -1591,29 +1638,30 @@ TEST_F(RenderViewImplTest, EditContextGetLayoutBoundsWithFloatingValues) {
// This RunLoop is waiting for EditContext to be created and layout bounds
// to be updated in the EditContext.
base::RunLoop run_loop;
- base::PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
run_loop.Run();
// Update the IME status and verify if our IME backend sends an IPC message
// to notify layout bounds of the EditContext.
main_widget()->UpdateTextInputState();
- auto params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
- EXPECT_EQ(true, std::get<0>(params).show_ime_if_needed);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
blink::WebRect edit_context_control_bounds_expected(10, 20, 31, 41);
blink::WebRect edit_context_selection_bounds_expected(10, 20, 1, 5);
main_widget()->ConvertViewportToWindow(&edit_context_control_bounds_expected);
main_widget()->ConvertViewportToWindow(
&edit_context_selection_bounds_expected);
blink::WebRect actual_active_element_control_bounds(
- std::get<0>(params).edit_context_control_bounds.value());
+ updated_states()[0]->edit_context_control_bounds.value());
blink::WebRect actual_active_element_selection_bounds(
- std::get<0>(params).edit_context_selection_bounds.value());
+ updated_states()[0]->edit_context_selection_bounds.value());
EXPECT_EQ(edit_context_control_bounds_expected,
actual_active_element_control_bounds);
EXPECT_EQ(edit_context_selection_bounds_expected,
actual_active_element_selection_bounds);
}
-TEST_F(RenderViewImplTest, ActiveElementGetLayoutBounds) {
+TEST_F(RenderViewImplTextInputStateChanged, ActiveElementGetLayoutBounds) {
// Load an HTML page consisting of one input fields.
LoadHTML(
"<html>"
@@ -1623,18 +1671,20 @@ TEST_F(RenderViewImplTest, ActiveElementGetLayoutBounds) {
"<input id=\"test\" type=\"text\"></input>"
"</body>"
"</html>");
- render_thread_->sink().ClearMessages();
+ ClearState();
// Create an EditContext with control and selection bounds and set input
// panel policy to auto.
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
// This RunLoop is waiting for focus to be processed for the active element.
base::RunLoop run_loop;
- base::PostTask(FROM_HERE, run_loop.QuitClosure());
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
run_loop.Run();
// Update the IME status and verify if our IME backend sends an IPC message
// to notify layout bounds of the EditContext.
main_widget()->UpdateTextInputState();
- auto params = ProcessAndReadIPC<WidgetHostMsg_TextInputStateChanged>();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
blink::WebInputMethodController* controller =
frame()->GetWebFrame()->GetInputMethodController();
blink::WebRect expected_control_bounds;
@@ -1642,10 +1692,152 @@ TEST_F(RenderViewImplTest, ActiveElementGetLayoutBounds) {
controller->GetLayoutBounds(&expected_control_bounds, &temp_selection_bounds);
main_widget()->ConvertViewportToWindow(&expected_control_bounds);
blink::WebRect actual_active_element_control_bounds(
- std::get<0>(params).edit_context_control_bounds.value());
+ updated_states()[0]->edit_context_control_bounds.value());
EXPECT_EQ(actual_active_element_control_bounds, expected_control_bounds);
}
+TEST_F(RenderViewImplTextInputStateChanged, VirtualKeyboardPolicyAuto) {
+ // Load an HTML page consisting of one input field.
+ LoadHTML(
+ "<html>"
+ "<head>"
+ "</head>"
+ "<body>"
+ "<input id=\"test\" type=\"text\"></input>"
+ "</body>"
+ "</html>");
+ ClearState();
+ // Set focus on the editable element.
+ ExecuteJavaScriptForTests("document.getElementById('test').focus();");
+ // This RunLoop is waiting for focus to be processed for the active element.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
+ run_loop.Run();
+ // Update the text input state and verify the virtualkeyboardpolicy attribute
+ // value.
+ main_widget()->UpdateTextInputState();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_EQ(updated_states()[0]->vk_policy,
+ ui::mojom::VirtualKeyboardPolicy::AUTO);
+}
+
+TEST_F(RenderViewImplTextInputStateChanged, VirtualKeyboardPolicyAutoToManual) {
+ // Load an HTML page consisting of one input field.
+ LoadHTML(
+ "<html>"
+ "<head>"
+ "</head>"
+ "<body>"
+ "<input id=\"test\" type=\"text\" "
+ "virtualkeyboardpolicy=\"manual\"></input>"
+ "</body>"
+ "</html>");
+ ClearState();
+ // Set focus on the editable element.
+ ExecuteJavaScriptForTests("document.getElementById('test').focus();");
+ // This RunLoop is waiting for focus to be processed for the active element.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
+ run_loop.Run();
+ // Update the IME status and verify if our IME backend sends an IPC message
+ // to notify virtualkeyboardpolicy change of the focused element.
+ main_widget()->UpdateTextInputState();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_EQ(updated_states()[0]->vk_policy,
+ ui::mojom::VirtualKeyboardPolicy::MANUAL);
+ EXPECT_EQ(updated_states()[0]->last_vk_visibility_request,
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE);
+}
+
+TEST_F(RenderViewImplTextInputStateChanged,
+ VirtualKeyboardPolicyManualAndShowHideAPIsCalled) {
+ // Load an HTML page consisting of two input fields.
+ LoadHTML(
+ "<html>"
+ "<head>"
+ "</head>"
+ "<body>"
+ "<input id=\"test1\" type=\"text\" "
+ "virtualkeyboardpolicy=\"manual\"></input>"
+ "<input id=\"test2\" type=\"text\" "
+ "virtualkeyboardpolicy=\"manual\"></input>"
+ "</body>"
+ "</html>");
+ ExecuteJavaScriptForTests(
+ "document.getElementById('test2').focus(); "
+ "navigator.virtualKeyboard.show();");
+ // This RunLoop is waiting for focus to be processed for the active element.
+ base::RunLoop run_loop1;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop1.QuitClosure());
+ run_loop1.Run();
+ // Update the IME status and verify if our IME backend sends an IPC message
+ // to notify virtualkeyboardpolicy change of the focused element and the show
+ // API call.
+ main_widget()->UpdateTextInputState();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_EQ(updated_states()[0]->vk_policy,
+ ui::mojom::VirtualKeyboardPolicy::MANUAL);
+ EXPECT_EQ(updated_states()[0]->last_vk_visibility_request,
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE);
+ ExecuteJavaScriptForTests(
+ "document.getElementById('test1').focus(); "
+ "navigator.virtualKeyboard.hide();");
+ base::RunLoop run_loop2;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop2.QuitClosure());
+ run_loop2.Run();
+ ClearState();
+ // Update the IME status and verify if our IME backend sends an IPC message
+ // to notify virtualkeyboardpolicy change of the focused element and the hide
+ // API call.
+ main_widget()->UpdateTextInputState();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_EQ(updated_states()[0]->vk_policy,
+ ui::mojom::VirtualKeyboardPolicy::MANUAL);
+ EXPECT_EQ(updated_states()[0]->last_vk_visibility_request,
+ ui::mojom::VirtualKeyboardVisibilityRequest::HIDE);
+}
+
+TEST_F(RenderViewImplTextInputStateChanged,
+ VirtualKeyboardPolicyAutoAndShowHideAPIsCalled) {
+ // Load an HTML page consisting of one input field.
+ LoadHTML(
+ "<html>"
+ "<head>"
+ "</head>"
+ "<body>"
+ "<input id=\"test1\" type=\"text\" "
+ "virtualkeyboardpolicy=\"auto\"></input>"
+ "</body>"
+ "</html>");
+ render_thread_->sink().ClearMessages();
+ ExecuteJavaScriptForTests(
+ "document.getElementById('test1').focus(); "
+ "navigator.virtualKeyboard.show();");
+ // This RunLoop is waiting for focus to be processed for the active element.
+ base::RunLoop run_loop;
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
+ run_loop.QuitClosure());
+ run_loop.Run();
+ // Update the IME status and verify if our IME backend sends an IPC message
+ // to notify virtualkeyboardpolicy change of the focused element and the show
+ // API call.
+ main_widget()->UpdateTextInputState();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(1u, updated_states().size());
+ EXPECT_EQ(updated_states()[0]->vk_policy,
+ ui::mojom::VirtualKeyboardPolicy::AUTO);
+ EXPECT_EQ(updated_states()[0]->last_vk_visibility_request,
+ ui::mojom::VirtualKeyboardVisibilityRequest::NONE);
+}
+
// Test that our IME backend can compose CJK words.
// Our IME front-end sends many platform-independent messages to the IME backend
// while it composes CJK words. This test sends the minimal messages captured
@@ -1739,31 +1931,31 @@ TEST_F(RenderViewImplTest, ImeComposition) {
case IME_SETFOCUS:
// Update the window focus.
- main_widget()->OnSetFocus(ime_message->enable);
+ GetWidgetInputHandler()->SetFocus(ime_message->enable);
break;
case IME_SETCOMPOSITION:
- main_widget()->OnImeSetComposition(
+ GetWidgetInputHandler()->ImeSetComposition(
base::WideToUTF16(ime_message->ime_string),
- std::vector<blink::WebImeTextSpan>(), gfx::Range::InvalidRange(),
+ std::vector<ui::ImeTextSpan>(), gfx::Range::InvalidRange(),
ime_message->selection_start, ime_message->selection_end);
break;
case IME_COMMITTEXT:
- main_widget()->OnImeCommitText(
+ GetWidgetInputHandler()->ImeCommitText(
base::WideToUTF16(ime_message->ime_string),
- std::vector<blink::WebImeTextSpan>(), gfx::Range::InvalidRange(),
- 0);
+ std::vector<ui::ImeTextSpan>(), gfx::Range::InvalidRange(), 0,
+ base::DoNothing());
break;
case IME_FINISHCOMPOSINGTEXT:
- main_widget()->OnImeFinishComposingText(false);
+ GetWidgetInputHandler()->ImeFinishComposingText(false);
break;
case IME_CANCELCOMPOSITION:
- main_widget()->OnImeSetComposition(base::string16(),
- std::vector<blink::WebImeTextSpan>(),
- gfx::Range::InvalidRange(), 0, 0);
+ GetWidgetInputHandler()->ImeSetComposition(
+ base::string16(), std::vector<ui::ImeTextSpan>(),
+ gfx::Range::InvalidRange(), 0, 0);
break;
}
@@ -1806,13 +1998,13 @@ TEST_F(RenderViewImplTest, OnSetTextDirection) {
base::i18n::TextDirection direction;
const wchar_t* expected_result;
} kTextDirection[] = {
- {base::i18n::RIGHT_TO_LEFT, L"rtl,rtl"},
- {base::i18n::LEFT_TO_RIGHT, L"ltr,ltr"},
+ {base::i18n::TextDirection::RIGHT_TO_LEFT, L"rtl,rtl"},
+ {base::i18n::TextDirection::LEFT_TO_RIGHT, L"ltr,ltr"},
};
for (auto& test_case : kTextDirection) {
// Set the text direction of the <textarea> element.
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
- ReceiveSetTextDirection(main_widget(), test_case.direction);
+ GetMainFrame()->SetTextDirectionForTesting(test_case.direction);
// Write the values of its DOM 'dir' attribute and its CSS 'direction'
// property to the <div> element.
@@ -2002,47 +2194,52 @@ TEST_F(RenderViewImplTest, GetCompositionCharacterBoundsTest) {
LoadHTML("<textarea id=\"test\" cols=\"100\"></textarea>");
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
+ auto* widget_input_handler = GetWidgetInputHandler();
const base::string16 empty_string;
- const std::vector<blink::WebImeTextSpan> empty_ime_text_span;
+ const std::vector<ui::ImeTextSpan> empty_ime_text_span;
std::vector<gfx::Rect> bounds;
- main_widget()->OnSetFocus(true);
+ widget_input_handler->SetFocus(true);
// ASCII composition
const base::string16 ascii_composition = base::UTF8ToUTF16("aiueo");
- main_widget()->OnImeSetComposition(ascii_composition, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0, 0);
- main_widget()->GetCompositionCharacterBounds(&bounds);
+ widget_input_handler->ImeSetComposition(
+ ascii_composition, empty_ime_text_span, gfx::Range::InvalidRange(), 0, 0);
+ bounds = LastCompositionBounds();
ASSERT_EQ(ascii_composition.size(), bounds.size());
for (const gfx::Rect& r : bounds)
EXPECT_LT(0, r.width());
- main_widget()->OnImeCommitText(empty_string,
- std::vector<blink::WebImeTextSpan>(),
- gfx::Range::InvalidRange(), 0);
+ widget_input_handler->ImeCommitText(
+ empty_string, std::vector<ui::ImeTextSpan>(), gfx::Range::InvalidRange(),
+ 0, base::DoNothing());
// Non surrogate pair unicode character.
const base::string16 unicode_composition = base::UTF8ToUTF16(
"\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A");
- main_widget()->OnImeSetComposition(unicode_composition, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0, 0);
- main_widget()->GetCompositionCharacterBounds(&bounds);
+ widget_input_handler->ImeSetComposition(unicode_composition,
+ empty_ime_text_span,
+ gfx::Range::InvalidRange(), 0, 0);
+ bounds = LastCompositionBounds();
ASSERT_EQ(unicode_composition.size(), bounds.size());
for (const gfx::Rect& r : bounds)
EXPECT_LT(0, r.width());
- main_widget()->OnImeCommitText(empty_string, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0);
+ widget_input_handler->ImeCommitText(empty_string, empty_ime_text_span,
+ gfx::Range::InvalidRange(), 0,
+ base::DoNothing());
// Surrogate pair character.
const base::string16 surrogate_pair_char =
base::UTF8ToUTF16("\xF0\xA0\xAE\x9F");
- main_widget()->OnImeSetComposition(surrogate_pair_char, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0, 0);
- main_widget()->GetCompositionCharacterBounds(&bounds);
+ widget_input_handler->ImeSetComposition(surrogate_pair_char,
+ empty_ime_text_span,
+ gfx::Range::InvalidRange(), 0, 0);
+ bounds = LastCompositionBounds();
ASSERT_EQ(surrogate_pair_char.size(), bounds.size());
EXPECT_LT(0, bounds[0].width());
EXPECT_EQ(0, bounds[1].width());
- main_widget()->OnImeCommitText(empty_string, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0);
+ widget_input_handler->ImeCommitText(empty_string, empty_ime_text_span,
+ gfx::Range::InvalidRange(), 0,
+ base::DoNothing());
// Mixed string.
const base::string16 surrogate_pair_mixed_composition =
@@ -2051,10 +2248,10 @@ TEST_F(RenderViewImplTest, GetCompositionCharacterBoundsTest) {
const size_t utf16_length = 8UL;
const bool is_surrogate_pair_empty_rect[8] = {
false, true, false, false, true, false, false, true };
- main_widget()->OnImeSetComposition(surrogate_pair_mixed_composition,
- empty_ime_text_span,
- gfx::Range::InvalidRange(), 0, 0);
- main_widget()->GetCompositionCharacterBounds(&bounds);
+ widget_input_handler->ImeSetComposition(surrogate_pair_mixed_composition,
+ empty_ime_text_span,
+ gfx::Range::InvalidRange(), 0, 0);
+ bounds = LastCompositionBounds();
ASSERT_EQ(utf16_length, bounds.size());
for (size_t i = 0; i < utf16_length; ++i) {
if (is_surrogate_pair_empty_rect[i]) {
@@ -2063,8 +2260,9 @@ TEST_F(RenderViewImplTest, GetCompositionCharacterBoundsTest) {
EXPECT_LT(0, bounds[i].width());
}
}
- main_widget()->OnImeCommitText(empty_string, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0);
+ widget_input_handler->ImeCommitText(empty_string, empty_ime_text_span,
+ gfx::Range::InvalidRange(), 0,
+ base::DoNothing());
}
#endif
@@ -2077,10 +2275,12 @@ TEST_F(RenderViewImplTest, SetEditableSelectionAndComposition) {
"<input id=\"test1\" value=\"some test text hello\"></input>"
"</body>"
"</html>");
+ auto* frame_widget_input_handler = GetFrameWidgetInputHandler();
ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
- frame()->SetEditableSelectionOffsets(4, 8);
+ frame_widget_input_handler->SetEditableSelectionOffsets(4, 8);
const std::vector<ui::ImeTextSpan> empty_ime_text_span;
- frame()->SetCompositionFromExistingText(7, 10, empty_ime_text_span);
+ frame_widget_input_handler->SetCompositionFromExistingText(
+ 7, 10, empty_ime_text_span);
base::RunLoop().RunUntilIdle();
blink::WebInputMethodController* controller =
frame()->GetWebFrame()->GetInputMethodController();
@@ -2089,7 +2289,7 @@ TEST_F(RenderViewImplTest, SetEditableSelectionAndComposition) {
EXPECT_EQ(8, info.selection_end);
EXPECT_EQ(7, info.composition_start);
EXPECT_EQ(10, info.composition_end);
- frame()->CollapseSelection();
+ frame_widget_input_handler->CollapseSelection();
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ(8, info.selection_start);
@@ -2105,9 +2305,10 @@ TEST_F(RenderViewImplTest, OnExtendSelectionAndDelete) {
"<input id=\"test1\" value=\"abcdefghijklmnopqrstuvwxyz\"></input>"
"</body>"
"</html>");
+ auto* frame_widget_input_handler = GetFrameWidgetInputHandler();
ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
- frame()->SetEditableSelectionOffsets(10, 10);
- frame()->ExtendSelectionAndDelete(3, 4);
+ frame_widget_input_handler->SetEditableSelectionOffsets(10, 10);
+ frame_widget_input_handler->ExtendSelectionAndDelete(3, 4);
base::RunLoop().RunUntilIdle();
blink::WebInputMethodController* controller =
frame()->GetWebFrame()->GetInputMethodController();
@@ -2115,8 +2316,8 @@ TEST_F(RenderViewImplTest, OnExtendSelectionAndDelete) {
EXPECT_EQ("abcdefgopqrstuvwxyz", info.value);
EXPECT_EQ(7, info.selection_start);
EXPECT_EQ(7, info.selection_end);
- frame()->SetEditableSelectionOffsets(4, 8);
- frame()->ExtendSelectionAndDelete(2, 5);
+ frame_widget_input_handler->SetEditableSelectionOffsets(4, 8);
+ frame_widget_input_handler->ExtendSelectionAndDelete(2, 5);
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ("abuvwxyz", info.value);
@@ -2136,8 +2337,9 @@ TEST_F(RenderViewImplTest, OnDeleteSurroundingText) {
"</html>");
ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
- frame()->SetEditableSelectionOffsets(10, 10);
- frame()->DeleteSurroundingText(3, 4);
+ auto* frame_widget_input_handler = GetFrameWidgetInputHandler();
+ frame_widget_input_handler->SetEditableSelectionOffsets(10, 10);
+ frame_widget_input_handler->DeleteSurroundingText(3, 4);
base::RunLoop().RunUntilIdle();
blink::WebInputMethodController* controller =
frame()->GetWebFrame()->GetInputMethodController();
@@ -2146,30 +2348,30 @@ TEST_F(RenderViewImplTest, OnDeleteSurroundingText) {
EXPECT_EQ(7, info.selection_start);
EXPECT_EQ(7, info.selection_end);
- frame()->SetEditableSelectionOffsets(4, 8);
- frame()->DeleteSurroundingText(2, 5);
+ frame_widget_input_handler->SetEditableSelectionOffsets(4, 8);
+ frame_widget_input_handler->DeleteSurroundingText(2, 5);
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ("abefgouvwxyz", info.value);
EXPECT_EQ(2, info.selection_start);
EXPECT_EQ(6, info.selection_end);
- frame()->SetEditableSelectionOffsets(5, 5);
- frame()->DeleteSurroundingText(10, 0);
+ frame_widget_input_handler->SetEditableSelectionOffsets(5, 5);
+ frame_widget_input_handler->DeleteSurroundingText(10, 0);
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ("ouvwxyz", info.value);
EXPECT_EQ(0, info.selection_start);
EXPECT_EQ(0, info.selection_end);
- frame()->DeleteSurroundingText(0, 10);
+ frame_widget_input_handler->DeleteSurroundingText(0, 10);
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ("", info.value);
EXPECT_EQ(0, info.selection_start);
EXPECT_EQ(0, info.selection_end);
- frame()->DeleteSurroundingText(10, 10);
+ frame_widget_input_handler->DeleteSurroundingText(10, 10);
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ("", info.value);
@@ -2193,8 +2395,9 @@ TEST_F(RenderViewImplTest, MAYBE_OnDeleteSurroundingTextInCodePoints) {
"<input id=\"test1\" value=\"ab&#x1f3c6; cdef&#x1f3c6; gh\">");
ExecuteJavaScriptForTests("document.getElementById('test1').focus();");
- frame()->SetEditableSelectionOffsets(4, 4);
- frame()->DeleteSurroundingTextInCodePoints(2, 2);
+ auto* frame_widget_input_handler = GetFrameWidgetInputHandler();
+ frame_widget_input_handler->SetEditableSelectionOffsets(4, 4);
+ frame_widget_input_handler->DeleteSurroundingTextInCodePoints(2, 2);
base::RunLoop().RunUntilIdle();
blink::WebInputMethodController* controller =
frame()->GetWebFrame()->GetInputMethodController();
@@ -2204,8 +2407,8 @@ TEST_F(RenderViewImplTest, MAYBE_OnDeleteSurroundingTextInCodePoints) {
EXPECT_EQ(1, info.selection_start);
EXPECT_EQ(1, info.selection_end);
- frame()->SetEditableSelectionOffsets(1, 3);
- frame()->DeleteSurroundingTextInCodePoints(1, 4);
+ frame_widget_input_handler->SetEditableSelectionOffsets(1, 3);
+ frame_widget_input_handler->DeleteSurroundingTextInCodePoints(1, 4);
base::RunLoop().RunUntilIdle();
info = controller->TextInputInfo();
EXPECT_EQ("deh", info.value);
@@ -2251,33 +2454,61 @@ TEST_F(RenderViewImplTest, BasicRenderFrame) {
EXPECT_TRUE(view()->main_render_frame_);
}
-TEST_F(RenderViewImplTest, MessageOrderInDidChangeSelection) {
+class MessageOrderFakeRenderWidgetHost : public FakeRenderWidgetHost,
+ public IPC::Listener {
+ public:
+ void TextInputStateChanged(ui::mojom::TextInputStatePtr state) override {
+ message_counter_++;
+ last_input_type_ = message_counter_;
+ }
+
+ ~MessageOrderFakeRenderWidgetHost() override {}
+
+ bool OnMessageReceived(const IPC::Message& message) override {
+ if (message.type() == FrameHostMsg_SelectionChanged::ID) {
+ base::RunLoop().RunUntilIdle();
+ message_counter_++;
+ last_selection_ = message_counter_;
+ }
+ return false;
+ }
+
+ uint32_t message_counter_ = 0;
+ uint32_t last_selection_ = 0;
+ uint32_t last_input_type_ = 0;
+};
+
+class RenderViewImplTextInputMessageOrder : public RenderViewImplTest {
+ public:
+ std::unique_ptr<FakeRenderWidgetHost> CreateRenderWidgetHost() override {
+ auto host = std::make_unique<MessageOrderFakeRenderWidgetHost>();
+ render_thread_->sink().AddFilter(host.get());
+ return host;
+ }
+
+ MessageOrderFakeRenderWidgetHost* GetMessageOrderFakeRenderWidgetHost() {
+ return static_cast<MessageOrderFakeRenderWidgetHost*>(
+ render_widget_host_.get());
+ }
+};
+
+TEST_F(RenderViewImplTextInputMessageOrder, MessageOrderInDidChangeSelection) {
LoadHTML("<textarea id=\"test\"></textarea>");
main_widget()->SetHandlingInputEvent(true);
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
- bool is_input_type_called = false;
- bool is_selection_called = false;
- size_t last_input_type = 0;
- size_t last_selection = 0;
-
- for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
- const uint32_t type = render_thread_->sink().GetMessageAt(i)->type();
- if (type == WidgetHostMsg_TextInputStateChanged::ID) {
- is_input_type_called = true;
- last_input_type = i;
- } else if (type == FrameHostMsg_SelectionChanged::ID) {
- is_selection_called = true;
- last_selection = i;
- }
- }
+ uint32_t last_input_type =
+ GetMessageOrderFakeRenderWidgetHost()->last_input_type_;
+ uint32_t last_selection =
+ GetMessageOrderFakeRenderWidgetHost()->last_selection_;
- EXPECT_TRUE(is_input_type_called);
- EXPECT_TRUE(is_selection_called);
+ EXPECT_NE(0u, last_input_type);
+ EXPECT_NE(0u, last_selection);
// InputTypeChange shold be called earlier than SelectionChanged.
EXPECT_LT(last_input_type, last_selection);
+ render_thread_->sink().RemoveFilter(GetMessageOrderFakeRenderWidgetHost());
}
class RendererErrorPageTest : public RenderViewImplTest {
@@ -2952,21 +3183,21 @@ TEST_F(RenderViewImplEnableZoomForDSFTest,
LoadHTML("<textarea id=\"test\"></textarea>");
ExecuteJavaScriptForTests("document.getElementById('test').focus();");
+ auto* widget_input_handler = GetWidgetInputHandler();
const base::string16 empty_string;
- const std::vector<blink::WebImeTextSpan> empty_ime_text_span;
+ const std::vector<ui::ImeTextSpan> empty_ime_text_span;
std::vector<gfx::Rect> bounds_at_1x;
- main_widget()->OnSetFocus(true);
+ widget_input_handler->SetFocus(true);
// ASCII composition
const base::string16 ascii_composition = base::UTF8ToUTF16("aiueo");
- main_widget()->OnImeSetComposition(ascii_composition, empty_ime_text_span,
- gfx::Range::InvalidRange(), 0, 0);
- main_widget()->GetCompositionCharacterBounds(&bounds_at_1x);
+ widget_input_handler->ImeSetComposition(
+ ascii_composition, empty_ime_text_span, gfx::Range::InvalidRange(), 0, 0);
+ bounds_at_1x = LastCompositionBounds();
ASSERT_EQ(ascii_composition.size(), bounds_at_1x.size());
SetDeviceScaleFactor(2.f);
- std::vector<gfx::Rect> bounds_at_2x;
- main_widget()->GetCompositionCharacterBounds(&bounds_at_2x);
+ std::vector<gfx::Rect> bounds_at_2x = LastCompositionBounds();
ASSERT_EQ(bounds_at_1x.size(), bounds_at_2x.size());
for (size_t i = 0; i < bounds_at_1x.size(); i++) {
const gfx::Rect& b1 = bounds_at_1x[i];