keyboard_controller_unittest.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 6ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/root_window.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/test/aura_test_helper.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/test/event_generator.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/test/test_window_delegate.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/window.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ime/input_method.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ime/input_method_factory.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ime/text_input_client.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/compositor/layer_type.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gfx/rect.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/keyboard/keyboard_controller.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/keyboard/keyboard_controller_proxy.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace keyboard { 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// An event handler that focuses a window when it is clicked/touched on. This is 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// used to match the focus manger behaviour in ash and views. 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestFocusController : public ui::EventHandler { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit TestFocusController(aura::RootWindow* root) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : root_(root) { 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_->AddPreTargetHandler(this); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~TestFocusController() { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_->RemovePreTargetHandler(this); 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from ui::EventHandler: 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnEvent(ui::Event* event) OVERRIDE { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* target = static_cast<aura::Window*>(event->target()); 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (event->type() == ui::ET_MOUSE_PRESSED || 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event->type() == ui::ET_TOUCH_PRESSED) { 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::GetFocusClient(target)->FocusWindow(target); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* root_; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestFocusController); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestKeyboardControllerProxy : public KeyboardControllerProxy { 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestKeyboardControllerProxy() 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : window_(new aura::Window(&delegate_)), 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) input_method_(ui::CreateInputMethod(NULL, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::kNullAcceleratedWidget)) { 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_->Init(ui::LAYER_NOT_DRAWN); 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_->set_owned_by_parent(false); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~TestKeyboardControllerProxy() { 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Destroy the window before the delegate. 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_.reset(); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from KeyboardControllerProxy: 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual aura::Window* GetKeyboardWindow() OVERRIDE { return window_.get(); } 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual content::BrowserContext* GetBrowserContext() OVERRIDE { return NULL; } 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ui::InputMethod* GetInputMethod() OVERRIDE { 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return input_method_.get(); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void RequestAudioInput(content::WebContents* web_contents, 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const content::MediaStreamRequest& request, 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const content::MediaResponseCallback& callback) OVERRIDE { return; } 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::Window> window_; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::test::TestWindowDelegate delegate_; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ui::InputMethod> input_method_; 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestKeyboardControllerProxy); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Keeps a count of all the events a window receives. 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class EventObserver : public ui::EventHandler { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EventObserver() {} 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~EventObserver() {} 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int GetEventCount(ui::EventType type) { 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return event_counts_[type]; 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from ui::EventHandler: 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnEvent(ui::Event* event) OVERRIDE { 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::EventHandler::OnEvent(event); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event_counts_[event->type()]++; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::map<ui::EventType, int> event_counts_; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EventObserver); 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TestTextInputClient : public ui::TextInputClient { 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit TestTextInputClient(ui::TextInputType type) 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : type_(type) {} 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~TestTextInputClient() {} 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Overridden from ui::TextInputClient: 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetCompositionText( 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ui::CompositionText& composition) OVERRIDE {} 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ConfirmCompositionText() OVERRIDE {} 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ClearCompositionText() OVERRIDE {} 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void InsertText(const base::string16& text) OVERRIDE {} 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void InsertChar(base::char16 ch, int flags) OVERRIDE {} 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual gfx::NativeWindow GetAttachedWindow() const OVERRIDE { 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return static_cast<gfx::NativeWindow>(NULL); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ui::TextInputType GetTextInputType() const OVERRIDE { 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return type_; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch virtual ui::TextInputMode GetTextInputMode() const OVERRIDE { 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return ui::TEXT_INPUT_MODE_DEFAULT; 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool CanComposeInline() const OVERRIDE { return false; } 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual gfx::Rect GetCaretBounds() OVERRIDE { return gfx::Rect(); } 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool GetCompositionCharacterBounds(uint32 index, 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect* rect) OVERRIDE { 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool HasCompositionText() OVERRIDE { return false; } 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool GetTextRange(ui::Range* range) OVERRIDE { return false; } 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool GetCompositionTextRange(ui::Range* range) OVERRIDE { 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool GetSelectionRange(ui::Range* range) OVERRIDE { return false; } 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool SetSelectionRange(const ui::Range& range) OVERRIDE { 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool DeleteRange(const ui::Range& range) OVERRIDE { return false; } 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool GetTextFromRange(const ui::Range& range, 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::string16* text) OVERRIDE { 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnInputMethodChanged() OVERRIDE {} 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool ChangeTextDirectionAndLayoutAlignment( 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::i18n::TextDirection direction) OVERRIDE { return false; } 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void ExtendSelectionAndDelete(size_t before, size_t after) OVERRIDE {} 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void EnsureCaretInRect(const gfx::Rect& rect) OVERRIDE {} 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::TextInputType type_; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestTextInputClient); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class KeyboardControllerTest : public testing::Test { 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardControllerTest() {} 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~KeyboardControllerTest() {} 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE { 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura_test_helper_->SetUp(); 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::SetUpInputMethodFactoryForTesting(); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_controller_.reset(new TestFocusController(root_window())); 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void TearDown() OVERRIDE { 176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch focus_controller_.reset(); 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura_test_helper_->TearDown(); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::RootWindow* root_window() { return aura_test_helper_->root_window(); } 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ShowKeyboard(KeyboardController* controller) { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestTextInputClient test_text_input_client(ui::TEXT_INPUT_TYPE_TEXT); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) controller->OnTextInputStateChanged(&test_text_input_client); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForUI message_loop_; 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<TestFocusController> focus_controller_; 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(KeyboardControllerTest, KeyboardSize) { 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardController controller(proxy); 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::Window> container(controller.GetContainerWindow()); 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bounds(0, 0, 100, 100); 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) container->SetBounds(bounds); 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Rect& before_bounds = proxy->GetKeyboardWindow()->bounds(); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect new_bounds( 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) before_bounds.x(), before_bounds.y(), 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) before_bounds.width() / 2, before_bounds.height() / 2); 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The KeyboardController's LayoutManager shouldn't let this happen 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) proxy->GetKeyboardWindow()->SetBounds(new_bounds); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_EQ(before_bounds, proxy->GetKeyboardWindow()->bounds()); 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tests that tapping/clicking inside the keyboard does not give it focus. 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) { 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Rect& root_bounds = root_window()->bounds(); 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::test::EventCountDelegate delegate; 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::Window> window(new aura::Window(&delegate)); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->Init(ui::LAYER_NOT_DRAWN); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->SetBounds(root_bounds); 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_window()->AddChild(window.get()); 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->Show(); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->Focus(); 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardController controller(proxy); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::Window> keyboard_container(controller.GetContainerWindow()); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) keyboard_container->SetBounds(root_bounds); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_window()->AddChild(keyboard_container.get()); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) keyboard_container->Show(); 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShowKeyboard(&controller); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(window->IsVisible()); 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(keyboard_container->IsVisible()); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(window->HasFocus()); 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(keyboard_container->HasFocus()); 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Click on the keyboard. Make sure the keyboard receives the event, but does 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // not get focus. 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EventObserver observer; 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) keyboard_container->AddPreTargetHandler(&observer); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::test::EventGenerator generator(root_window()); 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) generator.MoveMouseTo(proxy->GetKeyboardWindow()->bounds().CenterPoint()); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) generator.ClickLeftButton(); 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(window->HasFocus()); 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(keyboard_container->HasFocus()); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset()); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED)); 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED)); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Click outside of the keyboard. It should reach the window behind. 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) generator.MoveMouseTo(gfx::Point()); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) generator.ClickLeftButton(); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset()); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) { 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Rect& root_bounds = root_window()->bounds(); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::test::EventCountDelegate delegate; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::Window> window(new aura::Window(&delegate)); 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->Init(ui::LAYER_NOT_DRAWN); 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->SetBounds(root_bounds); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_window()->AddChild(window.get()); 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->Show(); 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window->Focus(); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui::InputMethod* input_method = proxy->GetInputMethod(); 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT); 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE); 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) input_method->SetFocusedTextInputClient(&input_client); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) KeyboardController controller(proxy); 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::Window> keyboard_container(controller.GetContainerWindow()); 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) keyboard_container->SetBounds(root_bounds); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_window()->AddChild(keyboard_container.get()); 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(keyboard_container->IsVisible()); 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) input_method->SetFocusedTextInputClient(&no_input_client); 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(keyboard_container->IsVisible()); 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) input_method->SetFocusedTextInputClient(&input_client); 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(keyboard_container->IsVisible()); 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace keyboard 293