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