OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
7 #include "testing/gtest/include/gtest/gtest.h" | 7 #include "testing/gtest/include/gtest/gtest.h" |
| 8 #include "ui/aura/client/focus_client.h" |
| 9 #include "ui/aura/root_window.h" |
8 #include "ui/aura/test/aura_test_helper.h" | 10 #include "ui/aura/test/aura_test_helper.h" |
| 11 #include "ui/aura/test/event_generator.h" |
| 12 #include "ui/aura/test/test_window_delegate.h" |
9 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
10 #include "ui/compositor/layer_type.h" | 14 #include "ui/compositor/layer_type.h" |
11 #include "ui/gfx/rect.h" | 15 #include "ui/gfx/rect.h" |
12 #include "ui/keyboard/keyboard_controller.h" | 16 #include "ui/keyboard/keyboard_controller.h" |
13 #include "ui/keyboard/keyboard_controller_proxy.h" | 17 #include "ui/keyboard/keyboard_controller_proxy.h" |
14 | 18 |
15 namespace keyboard { | 19 namespace keyboard { |
16 namespace { | 20 namespace { |
17 | 21 |
| 22 // An event handler that focuses a window when it is clicked/touched on. This is |
| 23 // used to match the focus manger behaviour in ash and views. |
| 24 class TestFocusController : public ui::EventHandler { |
| 25 public: |
| 26 explicit TestFocusController(aura::RootWindow* root) |
| 27 : root_(root) { |
| 28 root_->AddPreTargetHandler(this); |
| 29 } |
| 30 |
| 31 virtual ~TestFocusController() { |
| 32 root_->RemovePreTargetHandler(this); |
| 33 } |
| 34 |
| 35 private: |
| 36 // Overridden from ui::EventHandler: |
| 37 virtual void OnEvent(ui::Event* event) OVERRIDE { |
| 38 aura::Window* target = static_cast<aura::Window*>(event->target()); |
| 39 if (event->type() == ui::ET_MOUSE_PRESSED || |
| 40 event->type() == ui::ET_TOUCH_PRESSED) { |
| 41 aura::client::GetFocusClient(target)->FocusWindow(target); |
| 42 } |
| 43 } |
| 44 |
| 45 aura::Window* root_; |
| 46 DISALLOW_COPY_AND_ASSIGN(TestFocusController); |
| 47 }; |
| 48 |
18 class KeyboardControllerTest : public testing::Test { | 49 class KeyboardControllerTest : public testing::Test { |
19 public: | 50 public: |
20 KeyboardControllerTest() {} | 51 KeyboardControllerTest() {} |
21 virtual ~KeyboardControllerTest() {} | 52 virtual ~KeyboardControllerTest() {} |
22 | 53 |
23 virtual void SetUp() OVERRIDE { | 54 virtual void SetUp() OVERRIDE { |
24 aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); | 55 aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); |
25 aura_test_helper_->SetUp(); | 56 aura_test_helper_->SetUp(); |
| 57 focus_controller_.reset(new TestFocusController(root_window())); |
26 } | 58 } |
27 | 59 |
28 virtual void TearDown() OVERRIDE { | 60 virtual void TearDown() OVERRIDE { |
29 aura_test_helper_->TearDown(); | 61 aura_test_helper_->TearDown(); |
30 } | 62 } |
31 | 63 |
| 64 aura::RootWindow* root_window() { return aura_test_helper_->root_window(); } |
| 65 |
32 protected: | 66 protected: |
33 base::MessageLoopForUI message_loop_; | 67 base::MessageLoopForUI message_loop_; |
34 scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; | 68 scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_; |
| 69 scoped_ptr<TestFocusController> focus_controller_; |
35 | 70 |
36 private: | 71 private: |
37 DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); | 72 DISALLOW_COPY_AND_ASSIGN(KeyboardControllerTest); |
38 }; | 73 }; |
39 | 74 |
40 class TestKeyboardControllerProxy : public KeyboardControllerProxy { | 75 class TestKeyboardControllerProxy : public KeyboardControllerProxy { |
41 public: | 76 public: |
42 TestKeyboardControllerProxy() : window_(new aura::Window(NULL)) { | 77 TestKeyboardControllerProxy() : window_(new aura::Window(&delegate_)) { |
43 window_->Init(ui::LAYER_NOT_DRAWN); | 78 window_->Init(ui::LAYER_NOT_DRAWN); |
44 window_->set_owned_by_parent(false); | 79 window_->set_owned_by_parent(false); |
45 } | 80 } |
46 virtual ~TestKeyboardControllerProxy() {} | 81 |
| 82 virtual ~TestKeyboardControllerProxy() { |
| 83 // Destroy the window before the delegate. |
| 84 window_.reset(); |
| 85 } |
| 86 |
| 87 // Overridden from KeyboardControllerProxy: |
47 virtual aura::Window* GetKeyboardWindow() OVERRIDE { return window_.get(); } | 88 virtual aura::Window* GetKeyboardWindow() OVERRIDE { return window_.get(); } |
48 | 89 |
49 private: | 90 private: |
50 scoped_ptr<aura::Window> window_; | 91 scoped_ptr<aura::Window> window_; |
| 92 aura::test::TestWindowDelegate delegate_; |
| 93 |
51 DISALLOW_COPY_AND_ASSIGN(TestKeyboardControllerProxy); | 94 DISALLOW_COPY_AND_ASSIGN(TestKeyboardControllerProxy); |
52 }; | 95 }; |
53 | 96 |
| 97 // Keeps a count of all the events a window receives. |
| 98 class EventObserver : public ui::EventHandler { |
| 99 public: |
| 100 EventObserver() {} |
| 101 virtual ~EventObserver() {} |
| 102 |
| 103 int GetEventCount(ui::EventType type) { |
| 104 return event_counts_[type]; |
| 105 } |
| 106 |
| 107 private: |
| 108 // Overridden from ui::EventHandler: |
| 109 virtual void OnEvent(ui::Event* event) OVERRIDE { |
| 110 ui::EventHandler::OnEvent(event); |
| 111 event_counts_[event->type()]++; |
| 112 } |
| 113 |
| 114 std::map<ui::EventType, int> event_counts_; |
| 115 DISALLOW_COPY_AND_ASSIGN(EventObserver); |
| 116 }; |
| 117 |
54 } // namespace | 118 } // namespace |
55 | 119 |
56 TEST_F(KeyboardControllerTest, KeyboardSize) { | 120 TEST_F(KeyboardControllerTest, KeyboardSize) { |
57 KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); | 121 KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); |
58 KeyboardController controller(proxy); | 122 KeyboardController controller(proxy); |
59 | 123 |
60 scoped_ptr<aura::Window> container(controller.GetContainerWindow()); | 124 scoped_ptr<aura::Window> container(controller.GetContainerWindow()); |
61 gfx::Rect bounds(0, 0, 100, 100); | 125 gfx::Rect bounds(0, 0, 100, 100); |
62 container->SetBounds(bounds); | 126 container->SetBounds(bounds); |
63 | 127 |
64 const gfx::Rect& before_bounds = proxy->GetKeyboardWindow()->bounds(); | 128 const gfx::Rect& before_bounds = proxy->GetKeyboardWindow()->bounds(); |
65 gfx::Rect new_bounds( | 129 gfx::Rect new_bounds( |
66 before_bounds.x(), before_bounds.y(), | 130 before_bounds.x(), before_bounds.y(), |
67 before_bounds.width() / 2, before_bounds.height() / 2); | 131 before_bounds.width() / 2, before_bounds.height() / 2); |
68 | 132 |
69 // The KeyboardController's LayoutManager shouldn't let this happen | 133 // The KeyboardController's LayoutManager shouldn't let this happen |
70 proxy->GetKeyboardWindow()->SetBounds(new_bounds); | 134 proxy->GetKeyboardWindow()->SetBounds(new_bounds); |
71 ASSERT_EQ(before_bounds, proxy->GetKeyboardWindow()->bounds()); | 135 ASSERT_EQ(before_bounds, proxy->GetKeyboardWindow()->bounds()); |
72 } | 136 } |
73 | 137 |
| 138 // Tests that tapping/clicking inside the keyboard does not give it focus. |
| 139 TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) { |
| 140 const gfx::Rect& root_bounds = root_window()->bounds(); |
| 141 aura::test::EventCountDelegate delegate; |
| 142 scoped_ptr<aura::Window> window(new aura::Window(&delegate)); |
| 143 window->Init(ui::LAYER_NOT_DRAWN); |
| 144 window->SetBounds(root_bounds); |
| 145 root_window()->AddChild(window.get()); |
| 146 window->Show(); |
| 147 window->Focus(); |
| 148 |
| 149 KeyboardControllerProxy* proxy = new TestKeyboardControllerProxy(); |
| 150 KeyboardController controller(proxy); |
| 151 |
| 152 scoped_ptr<aura::Window> keyboard_container(controller.GetContainerWindow()); |
| 153 keyboard_container->SetBounds(root_bounds); |
| 154 |
| 155 root_window()->AddChild(keyboard_container.get()); |
| 156 keyboard_container->Show(); |
| 157 |
| 158 root_window()->StackChildAtTop(keyboard_container.get()); |
| 159 EXPECT_TRUE(window->IsVisible()); |
| 160 EXPECT_TRUE(keyboard_container->IsVisible()); |
| 161 EXPECT_TRUE(window->HasFocus()); |
| 162 EXPECT_FALSE(keyboard_container->HasFocus()); |
| 163 |
| 164 // Click on the keyboard. Make sure the keyboard receives the event, but does |
| 165 // not get focus. |
| 166 EventObserver observer; |
| 167 keyboard_container->AddPreTargetHandler(&observer); |
| 168 |
| 169 aura::test::EventGenerator generator(root_window()); |
| 170 generator.MoveMouseTo(proxy->GetKeyboardWindow()->bounds().CenterPoint()); |
| 171 generator.ClickLeftButton(); |
| 172 EXPECT_TRUE(window->HasFocus()); |
| 173 EXPECT_FALSE(keyboard_container->HasFocus()); |
| 174 EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset()); |
| 175 EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_PRESSED)); |
| 176 EXPECT_EQ(1, observer.GetEventCount(ui::ET_MOUSE_RELEASED)); |
| 177 |
| 178 // Click outside of the keyboard. It should reach the window behind. |
| 179 generator.MoveMouseTo(gfx::Point()); |
| 180 generator.ClickLeftButton(); |
| 181 EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset()); |
| 182 } |
| 183 |
74 } // namespace keyboard | 184 } // namespace keyboard |
OLD | NEW |