1 // Copyright 2014 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 "base/command_line.h" 6 #include "chrome/test/base/in_process_browser_test.h" 7 #include "content/public/browser/web_contents.h" 8 #include "ui/base/ime/dummy_text_input_client.h" 9 #include "ui/base/ime/input_method.h" 10 #include "ui/base/ime/input_method_factory.h" 11 #include "ui/keyboard/keyboard_constants.h" 12 #include "ui/keyboard/keyboard_controller.h" 13 #include "ui/keyboard/keyboard_controller_proxy.h" 14 #include "ui/keyboard/keyboard_switches.h" 15 #include "ui/keyboard/keyboard_util.h" 16 17 namespace { 18 const int kKeyboardHeightForTest = 100; 19 } // namespace 20 21 class VirtualKeyboardWebContentTest : public InProcessBrowserTest { 22 public: 23 VirtualKeyboardWebContentTest() {}; 24 virtual ~VirtualKeyboardWebContentTest() {}; 25 26 virtual void SetUp() OVERRIDE { 27 ui::SetUpInputMethodFactoryForTesting(); 28 InProcessBrowserTest::SetUp(); 29 } 30 31 // Ensure that the virtual keyboard is enabled. 32 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 33 command_line->AppendSwitch( 34 keyboard::switches::kEnableVirtualKeyboard); 35 } 36 37 keyboard::KeyboardControllerProxy* proxy() { 38 return keyboard::KeyboardController::GetInstance()->proxy(); 39 } 40 41 protected: 42 void FocusEditableNodeAndShowKeyboard() { 43 client.reset(new ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_TEXT)); 44 ui::InputMethod* input_method = proxy()->GetInputMethod(); 45 input_method->SetFocusedTextInputClient(client.get()); 46 input_method->ShowImeIfNeeded(); 47 ResizeKeyboardWindow(); 48 } 49 50 void FocusNonEditableNode() { 51 client.reset(new ui::DummyTextInputClient(ui::TEXT_INPUT_TYPE_NONE)); 52 ui::InputMethod* input_method = proxy()->GetInputMethod(); 53 input_method->SetFocusedTextInputClient(client.get()); 54 } 55 56 void MockEnableIMEInDifferentExtension(const std::string& url) { 57 keyboard::SetOverrideContentUrl(GURL(url)); 58 keyboard::KeyboardController::GetInstance()->Reload(); 59 ResizeKeyboardWindow(); 60 } 61 62 bool IsKeyboardVisible() const { 63 return keyboard::KeyboardController::GetInstance()->keyboard_visible(); 64 } 65 66 private: 67 // Mock window.resizeTo that is expected to be called after navigate to a new 68 // virtual keyboard. 69 void ResizeKeyboardWindow() { 70 gfx::Rect bounds = proxy()->GetKeyboardWindow()->bounds(); 71 proxy()->GetKeyboardWindow()->SetBounds(gfx::Rect( 72 bounds.x(), 73 bounds.bottom() - kKeyboardHeightForTest, 74 bounds.width(), 75 kKeyboardHeightForTest)); 76 } 77 78 scoped_ptr<ui::DummyTextInputClient> client; 79 80 DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardWebContentTest); 81 }; 82 83 // Test for crbug.com/404340. After enabling an IME in a different extension, 84 // its virtual keyboard should not become visible if previous one is not. 85 IN_PROC_BROWSER_TEST_F(VirtualKeyboardWebContentTest, 86 EnableIMEInDifferentExtension) { 87 FocusEditableNodeAndShowKeyboard(); 88 EXPECT_TRUE(IsKeyboardVisible()); 89 FocusNonEditableNode(); 90 EXPECT_FALSE(IsKeyboardVisible()); 91 92 MockEnableIMEInDifferentExtension("chrome-extension://domain-1"); 93 // Keyboard should not become visible if previous keyboard is not. 94 EXPECT_FALSE(IsKeyboardVisible()); 95 96 FocusEditableNodeAndShowKeyboard(); 97 // Keyboard should become visible after focus on an editable node. 98 EXPECT_TRUE(IsKeyboardVisible()); 99 100 // Simulate hide keyboard by pressing hide key on the virtual keyboard. 101 keyboard::KeyboardController::GetInstance()->HideKeyboard( 102 keyboard::KeyboardController::HIDE_REASON_MANUAL); 103 EXPECT_FALSE(IsKeyboardVisible()); 104 105 MockEnableIMEInDifferentExtension("chrome-extension://domain-2"); 106 // Keyboard should not become visible if previous keyboard is not, even if it 107 // is currently focused on an editable node. 108 EXPECT_FALSE(IsKeyboardVisible()); 109 } 110