Home | History | Annotate | Download | only in renderer_host
      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