Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ash / focus_cycler_unittest.cc
blob74569d300016bee6579f679ece343893af9cf4ba
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.
5 #include "ash/focus_cycler.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/shelf/shelf.h"
9 #include "ash/shelf/shelf_widget.h"
10 #include "ash/shell.h"
11 #include "ash/shell_factory.h"
12 #include "ash/shell_window_ids.h"
13 #include "ash/system/status_area_widget.h"
14 #include "ash/system/status_area_widget_delegate.h"
15 #include "ash/system/tray/system_tray.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/wm/window_util.h"
18 #include "ui/aura/test/test_windows.h"
19 #include "ui/aura/window.h"
20 #include "ui/aura/window_event_dispatcher.h"
21 #include "ui/events/test/event_generator.h"
22 #include "ui/views/accessible_pane_view.h"
23 #include "ui/views/controls/button/menu_button.h"
24 #include "ui/views/widget/widget.h"
26 namespace ash {
27 namespace test {
29 using aura::Window;
31 namespace {
33 StatusAreaWidgetDelegate* GetStatusAreaWidgetDelegate(views::Widget* widget) {
34 return static_cast<StatusAreaWidgetDelegate*>(widget->GetContentsView());
37 class PanedWidgetDelegate : public views::WidgetDelegate {
38 public:
39 PanedWidgetDelegate(views::Widget* widget) : widget_(widget) {}
41 void SetAccessiblePanes(const std::vector<views::View*>& panes) {
42 accessible_panes_ = panes;
45 // views::WidgetDelegate.
46 virtual void GetAccessiblePanes(std::vector<views::View*>* panes) OVERRIDE {
47 std::copy(accessible_panes_.begin(),
48 accessible_panes_.end(),
49 std::back_inserter(*panes));
51 virtual views::Widget* GetWidget() OVERRIDE {
52 return widget_;
54 virtual const views::Widget* GetWidget() const OVERRIDE {
55 return widget_;
58 private:
59 views::Widget* widget_;
60 std::vector<views::View*> accessible_panes_;
63 } // namespace
65 class FocusCyclerTest : public AshTestBase {
66 public:
67 FocusCyclerTest() {}
69 virtual void SetUp() OVERRIDE {
70 AshTestBase::SetUp();
72 focus_cycler_.reset(new FocusCycler());
74 ASSERT_TRUE(Shelf::ForPrimaryDisplay());
77 virtual void TearDown() OVERRIDE {
78 if (tray_) {
79 GetStatusAreaWidgetDelegate(tray_->GetWidget())->
80 SetFocusCyclerForTesting(NULL);
81 tray_.reset();
84 shelf_widget()->SetFocusCycler(NULL);
86 focus_cycler_.reset();
88 AshTestBase::TearDown();
91 protected:
92 // Creates the system tray, returning true on success.
93 bool CreateTray() {
94 if (tray_)
95 return false;
96 aura::Window* parent =
97 Shell::GetPrimaryRootWindowController()->GetContainer(
98 ash::kShellWindowId_StatusContainer);
100 StatusAreaWidget* widget = new StatusAreaWidget(parent);
101 widget->CreateTrayViews();
102 widget->Show();
103 tray_.reset(widget->system_tray());
104 if (!tray_->GetWidget())
105 return false;
106 focus_cycler_->AddWidget(tray()->GetWidget());
107 GetStatusAreaWidgetDelegate(tray_->GetWidget())->SetFocusCyclerForTesting(
108 focus_cycler());
109 return true;
112 FocusCycler* focus_cycler() { return focus_cycler_.get(); }
114 SystemTray* tray() { return tray_.get(); }
116 ShelfWidget* shelf_widget() {
117 return Shelf::ForPrimaryDisplay()->shelf_widget();
120 void InstallFocusCycleOnShelf() {
121 // Add the shelf.
122 shelf_widget()->SetFocusCycler(focus_cycler());
125 private:
126 scoped_ptr<FocusCycler> focus_cycler_;
127 scoped_ptr<SystemTray> tray_;
129 DISALLOW_COPY_AND_ASSIGN(FocusCyclerTest);
132 TEST_F(FocusCyclerTest, CycleFocusBrowserOnly) {
133 // Create a single test window.
134 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
135 wm::ActivateWindow(window0.get());
136 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
138 // Cycle the window
139 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
140 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
143 TEST_F(FocusCyclerTest, CycleFocusForward) {
144 ASSERT_TRUE(CreateTray());
146 InstallFocusCycleOnShelf();
148 // Create a single test window.
149 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
150 wm::ActivateWindow(window0.get());
151 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
153 // Cycle focus to the status area.
154 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
155 EXPECT_TRUE(tray()->GetWidget()->IsActive());
157 // Cycle focus to the shelf.
158 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
159 EXPECT_TRUE(shelf_widget()->IsActive());
161 // Cycle focus to the browser.
162 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
163 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
166 TEST_F(FocusCyclerTest, CycleFocusBackward) {
167 ASSERT_TRUE(CreateTray());
169 InstallFocusCycleOnShelf();
171 // Create a single test window.
172 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
173 wm::ActivateWindow(window0.get());
174 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
176 // Cycle focus to the shelf.
177 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
178 EXPECT_TRUE(shelf_widget()->IsActive());
180 // Cycle focus to the status area.
181 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
182 EXPECT_TRUE(tray()->GetWidget()->IsActive());
184 // Cycle focus to the browser.
185 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
186 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
189 TEST_F(FocusCyclerTest, CycleFocusForwardBackward) {
190 ASSERT_TRUE(CreateTray());
192 InstallFocusCycleOnShelf();
194 // Create a single test window.
195 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
196 wm::ActivateWindow(window0.get());
197 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
199 // Cycle focus to the shelf.
200 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
201 EXPECT_TRUE(shelf_widget()->IsActive());
203 // Cycle focus to the status area.
204 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
205 EXPECT_TRUE(tray()->GetWidget()->IsActive());
207 // Cycle focus to the browser.
208 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
209 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
211 // Cycle focus to the status area.
212 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
213 EXPECT_TRUE(tray()->GetWidget()->IsActive());
215 // Cycle focus to the shelf.
216 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
217 EXPECT_TRUE(shelf_widget()->IsActive());
219 // Cycle focus to the browser.
220 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
221 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
224 TEST_F(FocusCyclerTest, CycleFocusNoBrowser) {
225 ASSERT_TRUE(CreateTray());
227 InstallFocusCycleOnShelf();
229 // Add the shelf and focus it.
230 focus_cycler()->FocusWidget(shelf_widget());
232 // Cycle focus to the status area.
233 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
234 EXPECT_TRUE(tray()->GetWidget()->IsActive());
236 // Cycle focus to the shelf.
237 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
238 EXPECT_TRUE(shelf_widget()->IsActive());
240 // Cycle focus to the status area.
241 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
242 EXPECT_TRUE(tray()->GetWidget()->IsActive());
244 // Cycle focus to the shelf.
245 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
246 EXPECT_TRUE(shelf_widget()->IsActive());
248 // Cycle focus to the status area.
249 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
250 EXPECT_TRUE(tray()->GetWidget()->IsActive());
253 // Tests that focus cycles from the active browser to the status area and back.
254 TEST_F(FocusCyclerTest, Shelf_CycleFocusForward) {
255 ASSERT_TRUE(CreateTray());
256 InstallFocusCycleOnShelf();
257 shelf_widget()->Hide();
259 // Create two test windows.
260 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
261 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
262 wm::ActivateWindow(window1.get());
263 wm::ActivateWindow(window0.get());
264 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
266 // Cycle focus to the status area.
267 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
268 EXPECT_TRUE(tray()->GetWidget()->IsActive());
270 // Cycle focus to the browser.
271 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
272 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
274 // Cycle focus to the status area.
275 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
276 EXPECT_TRUE(tray()->GetWidget()->IsActive());
279 TEST_F(FocusCyclerTest, Shelf_CycleFocusBackwardInvisible) {
280 ASSERT_TRUE(CreateTray());
281 InstallFocusCycleOnShelf();
282 shelf_widget()->Hide();
284 // Create a single test window.
285 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
286 wm::ActivateWindow(window0.get());
287 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
289 // Cycle focus to the status area.
290 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
291 EXPECT_TRUE(tray()->GetWidget()->IsActive());
293 // Cycle focus to the browser.
294 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
295 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
298 TEST_F(FocusCyclerTest, CycleFocusThroughWindowWithPanes) {
299 ASSERT_TRUE(CreateTray());
301 InstallFocusCycleOnShelf();
303 scoped_ptr<PanedWidgetDelegate> test_widget_delegate;
304 scoped_ptr<views::Widget> browser_widget(new views::Widget);
305 test_widget_delegate.reset(new PanedWidgetDelegate(browser_widget.get()));
306 views::Widget::InitParams widget_params(
307 views::Widget::InitParams::TYPE_WINDOW);
308 widget_params.context = CurrentContext();
309 widget_params.delegate = test_widget_delegate.get();
310 widget_params.ownership =
311 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
312 browser_widget->Init(widget_params);
313 browser_widget->Show();
315 aura::Window* browser_window = browser_widget->GetNativeView();
317 views::View* root_view = browser_widget->GetRootView();
319 views::AccessiblePaneView* pane1 = new views::AccessiblePaneView();
320 root_view->AddChildView(pane1);
322 views::View* view1 = new views::View;
323 view1->SetFocusable(true);
324 pane1->AddChildView(view1);
326 views::View* view2 = new views::View;
327 view2->SetFocusable(true);
328 pane1->AddChildView(view2);
330 views::AccessiblePaneView* pane2 = new views::AccessiblePaneView();
331 root_view->AddChildView(pane2);
333 views::View* view3 = new views::View;
334 view3->SetFocusable(true);
335 pane2->AddChildView(view3);
337 views::View* view4 = new views::View;
338 view4->SetFocusable(true);
339 pane2->AddChildView(view4);
341 std::vector<views::View*> panes;
342 panes.push_back(pane1);
343 panes.push_back(pane2);
345 test_widget_delegate->SetAccessiblePanes(panes);
347 views::FocusManager* focus_manager = browser_widget->GetFocusManager();
349 // Cycle focus to the status area.
350 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
351 EXPECT_TRUE(tray()->GetWidget()->IsActive());
353 // Cycle focus to the shelf.
354 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
355 EXPECT_TRUE(shelf_widget()->IsActive());
357 // Cycle focus to the first pane in the browser.
358 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
359 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
360 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
362 // Cycle focus to the second pane in the browser.
363 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
364 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
365 EXPECT_EQ(focus_manager->GetFocusedView(), view3);
367 // Cycle focus back to the status area.
368 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
369 EXPECT_TRUE(tray()->GetWidget()->IsActive());
371 // Reverse direction - back to the second pane in the browser.
372 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
373 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
374 EXPECT_EQ(focus_manager->GetFocusedView(), view3);
376 // Back to the first pane in the browser.
377 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
378 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
379 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
381 // Back to the shelf.
382 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
383 EXPECT_TRUE(shelf_widget()->IsActive());
385 // Back to the status area.
386 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
387 EXPECT_TRUE(tray()->GetWidget()->IsActive());
389 // Pressing "Escape" while on the status area should
390 // deactivate it, and activate the browser window.
391 aura::Window* root = Shell::GetPrimaryRootWindow();
392 ui::test::EventGenerator event_generator(root, root);
393 event_generator.PressKey(ui::VKEY_ESCAPE, 0);
394 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
395 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
397 // Similarly, pressing "Escape" while on the shelf.
398 // should do the same thing.
399 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
400 EXPECT_TRUE(shelf_widget()->IsActive());
401 event_generator.PressKey(ui::VKEY_ESCAPE, 0);
402 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
403 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
406 } // namespace test
407 } // namespace ash