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 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/command_line.h" 8 #include "base/win/metro.h" 9 #include "content/browser/renderer_host/render_widget_host_view_win.h" 10 #include "content/public/browser/render_view_host.h" 11 #include "content/public/browser/web_contents.h" 12 #include "content/public/common/content_switches.h" 13 #include "content/public/test/test_utils.h" 14 #include "content/public/test/browser_test_utils.h" 15 #include "content/shell/shell.h" 16 #include "content/test/content_browser_test_utils.h" 17 #include "content/test/content_browser_test.h" 18 #include "ui/base/ime/composition_text.h" 19 #include "ui/base/ime/text_input_type.h" 20 #include "ui/base/ime/win/imm32_manager.h" 21 #include "ui/base/ime/win/mock_tsf_bridge.h" 22 #include "ui/base/ime/win/tsf_bridge.h" 23 24 namespace content { 25 namespace { 26 27 class MockIMM32Manager : public ui::IMM32Manager { 28 public: 29 MockIMM32Manager() 30 : window_handle_(NULL), 31 input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), 32 call_count_(0) { 33 } 34 virtual ~MockIMM32Manager() {} 35 36 virtual void SetTextInputMode(HWND window_handle, 37 ui::TextInputMode input_mode) OVERRIDE { 38 ++call_count_; 39 window_handle_ = window_handle; 40 input_mode_ = input_mode; 41 } 42 43 void Reset() { 44 window_handle_ = NULL; 45 input_mode_ = ui::TEXT_INPUT_MODE_DEFAULT; 46 call_count_ = 0; 47 } 48 49 HWND window_handle() const { return window_handle_; } 50 ui::TextInputMode input_mode() const { return input_mode_; } 51 size_t call_count() const { return call_count_; } 52 53 private: 54 HWND window_handle_; 55 ui::TextInputMode input_mode_; 56 size_t call_count_; 57 58 DISALLOW_COPY_AND_ASSIGN(MockIMM32Manager); 59 }; 60 61 // Testing class serving initialized RenderWidgetHostViewWin instance; 62 class RenderWidgetHostViewWinBrowserTest : public ContentBrowserTest { 63 public: 64 RenderWidgetHostViewWinBrowserTest() {} 65 66 virtual void SetUpOnMainThread() OVERRIDE { 67 ContentBrowserTest::SetUpOnMainThread(); 68 69 NavigateToURL(shell(), GURL("about:blank")); 70 71 view_ = static_cast<RenderWidgetHostViewWin*>( 72 RenderWidgetHostViewPort::FromRWHV( 73 shell()->web_contents()->GetRenderViewHost()->GetView())); 74 CHECK(view_); 75 } 76 77 protected: 78 RenderWidgetHostViewWin* view_; 79 }; 80 81 } // namespace 82 83 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewWinBrowserTest, 84 TextInputTypeChanged) { 85 ASSERT_TRUE(view_->m_hWnd); 86 87 MockIMM32Manager* mock = new MockIMM32Manager(); 88 mock->Reset(); 89 view_->imm32_manager_.reset(mock); 90 view_->TextInputTypeChanged(ui::TEXT_INPUT_TYPE_NONE, false, 91 ui::TEXT_INPUT_MODE_EMAIL); 92 93 EXPECT_EQ(1, mock->call_count()); 94 EXPECT_EQ(view_->m_hWnd, mock->window_handle()); 95 EXPECT_EQ(ui::TEXT_INPUT_MODE_EMAIL, mock->input_mode()); 96 97 mock->Reset(); 98 view_->TextInputTypeChanged(ui::TEXT_INPUT_TYPE_NONE, false, 99 ui::TEXT_INPUT_MODE_EMAIL); 100 EXPECT_EQ(0, mock->call_count()); 101 } 102 103 class RenderWidgetHostViewWinTSFTest : public ContentBrowserTest { 104 public: 105 RenderWidgetHostViewWinTSFTest() {} 106 107 virtual void SetUpCommandLine(CommandLine* command_line) { 108 command_line->AppendSwitch(switches::kEnableTextServicesFramework); 109 } 110 }; 111 112 // crbug.com/151798 113 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewWinTSFTest, 114 DISABLED_SwichToPasswordField) { 115 ui::MockTSFBridge mock_bridge; 116 ui::TSFBridge* old_bridge = ui::TSFBridge::ReplaceForTesting(&mock_bridge); 117 GURL test_url = GetTestUrl("textinput", "ime_enable_disable_test.html"); 118 119 NavigateToURL(shell(), test_url); 120 WaitForLoadStop(shell()->web_contents()); 121 RunAllPendingInMessageLoop(); 122 123 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, mock_bridge.latest_text_iput_type()); 124 125 // Focus to the text field, the IME should be enabled. 126 bool success = false; 127 EXPECT_TRUE(ExecuteScriptAndExtractBool( 128 shell()->web_contents(), 129 "window.domAutomationController.send(text01_focus());", 130 &success)); 131 EXPECT_TRUE(success); 132 WaitForLoadStop(shell()->web_contents()); 133 RunAllPendingInMessageLoop(); 134 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, mock_bridge.latest_text_iput_type()); 135 136 // Focus to the password field, the IME should be disabled. 137 success = false; 138 EXPECT_TRUE(ExecuteScriptAndExtractBool( 139 shell()->web_contents(), 140 "window.domAutomationController.send(password02_focus());", 141 &success)); 142 EXPECT_TRUE(success); 143 WaitForLoadStop(shell()->web_contents()); 144 RunAllPendingInMessageLoop(); 145 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, mock_bridge.latest_text_iput_type()); 146 147 ui::TSFBridge::ReplaceForTesting(old_bridge); 148 } 149 150 // crbug.com/151798 151 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewWinTSFTest, 152 DISABLED_SwitchToSameField) { 153 ui::MockTSFBridge mock_bridge; 154 ui::TSFBridge* old_bridge = ui::TSFBridge::ReplaceForTesting(&mock_bridge); 155 GURL test_url = GetTestUrl("textinput", "ime_enable_disable_test.html"); 156 157 NavigateToURL(shell(), test_url); 158 WaitForLoadStop(shell()->web_contents()); 159 RunAllPendingInMessageLoop(); 160 161 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, mock_bridge.latest_text_iput_type()); 162 163 // Focus to the text field, the IME should be enabled. 164 bool success = false; 165 EXPECT_TRUE(ExecuteScriptAndExtractBool( 166 shell()->web_contents(), 167 "window.domAutomationController.send(text01_focus());", 168 &success)); 169 EXPECT_TRUE(success); 170 WaitForLoadStop(shell()->web_contents()); 171 RunAllPendingInMessageLoop(); 172 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, mock_bridge.latest_text_iput_type()); 173 174 // Focus to another text field, the IME should be enabled. 175 success = false; 176 EXPECT_TRUE(ExecuteScriptAndExtractBool( 177 shell()->web_contents(), 178 "window.domAutomationController.send(text02_focus());", 179 &success)); 180 EXPECT_TRUE(success); 181 WaitForLoadStop(shell()->web_contents()); 182 RunAllPendingInMessageLoop(); 183 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, mock_bridge.latest_text_iput_type()); 184 185 ui::TSFBridge::ReplaceForTesting(old_bridge); 186 } 187 188 // crbug.com/151798 189 IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewWinTSFTest, 190 DISABLED_SwitchToSamePasswordField) { 191 ui::MockTSFBridge mock_bridge; 192 ui::TSFBridge* old_bridge = ui::TSFBridge::ReplaceForTesting(&mock_bridge); 193 GURL test_url = GetTestUrl("textinput", "ime_enable_disable_test.html"); 194 195 NavigateToURL(shell(), test_url); 196 WaitForLoadStop(shell()->web_contents()); 197 RunAllPendingInMessageLoop(); 198 199 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, mock_bridge.latest_text_iput_type()); 200 201 // Focus to the password field, the IME should be disabled. 202 bool success = false; 203 EXPECT_TRUE(ExecuteScriptAndExtractBool( 204 shell()->web_contents(), 205 "window.domAutomationController.send(password01_focus());", 206 &success)); 207 EXPECT_TRUE(success); 208 WaitForLoadStop(shell()->web_contents()); 209 RunAllPendingInMessageLoop(); 210 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, mock_bridge.latest_text_iput_type()); 211 212 // Focus to the another password field, the IME should be disabled. 213 success = false; 214 EXPECT_TRUE(ExecuteScriptAndExtractBool( 215 shell()->web_contents(), 216 "window.domAutomationController.send(password02_focus());", 217 &success)); 218 EXPECT_TRUE(success); 219 WaitForLoadStop(shell()->web_contents()); 220 RunAllPendingInMessageLoop(); 221 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, mock_bridge.latest_text_iput_type()); 222 223 ui::TSFBridge::ReplaceForTesting(old_bridge); 224 } 225 226 } // namespace content 227