Replace the deprecated __attribute__((no_address_safety_analysis))
[chromium-blink-merge.git] / ash / focus_cycler_unittest.cc
blob8c02491df999f356bc005a394ce344cd1bd88be9
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/launcher/launcher.h"
8 #include "ash/root_window_controller.h"
9 #include "ash/shelf/shelf_widget.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "ash/system/status_area_widget.h"
13 #include "ash/system/status_area_widget_delegate.h"
14 #include "ash/system/tray/system_tray.h"
15 #include "ash/wm/window_util.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/shell_factory.h"
18 #include "ui/aura/root_window.h"
19 #include "ui/aura/test/event_generator.h"
20 #include "ui/aura/test/test_windows.h"
21 #include "ui/aura/window.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;
30 using internal::FocusCycler;
32 namespace {
34 internal::StatusAreaWidgetDelegate* GetStatusAreaWidgetDelegate(
35 views::Widget* widget) {
36 return static_cast<internal::StatusAreaWidgetDelegate*>(
37 widget->GetContentsView());
40 class PanedWidgetDelegate : public views::WidgetDelegate {
41 public:
42 PanedWidgetDelegate(views::Widget* widget) : widget_(widget) {}
44 void SetAccessiblePanes(const std::vector<views::View*>& panes) {
45 accessible_panes_ = panes;
48 // views::WidgetDelegate.
49 virtual void GetAccessiblePanes(std::vector<views::View*>* panes) OVERRIDE {
50 std::copy(accessible_panes_.begin(),
51 accessible_panes_.end(),
52 std::back_inserter(*panes));
54 virtual views::Widget* GetWidget() OVERRIDE {
55 return widget_;
57 virtual const views::Widget* GetWidget() const OVERRIDE {
58 return widget_;
61 private:
62 views::Widget* widget_;
63 std::vector<views::View*> accessible_panes_;
66 } // namespace
68 class FocusCyclerTest : public AshTestBase {
69 public:
70 FocusCyclerTest() {}
72 virtual void SetUp() OVERRIDE {
73 AshTestBase::SetUp();
75 focus_cycler_.reset(new FocusCycler());
77 ASSERT_TRUE(Launcher::ForPrimaryDisplay());
80 virtual void TearDown() OVERRIDE {
81 if (tray_) {
82 GetStatusAreaWidgetDelegate(tray_->GetWidget())->
83 SetFocusCyclerForTesting(NULL);
84 tray_.reset();
87 shelf_widget()->SetFocusCycler(NULL);
89 focus_cycler_.reset();
91 AshTestBase::TearDown();
94 protected:
95 // Creates the system tray, returning true on success.
96 bool CreateTray() {
97 if (tray_)
98 return false;
99 aura::Window* parent = Shell::GetPrimaryRootWindowController()->
100 GetContainer(ash::internal::kShellWindowId_StatusContainer);
102 internal::StatusAreaWidget* widget = new internal::StatusAreaWidget(parent);
103 widget->CreateTrayViews();
104 widget->Show();
105 tray_.reset(widget->system_tray());
106 if (!tray_->GetWidget())
107 return false;
108 focus_cycler_->AddWidget(tray()->GetWidget());
109 GetStatusAreaWidgetDelegate(tray_->GetWidget())->SetFocusCyclerForTesting(
110 focus_cycler());
111 return true;
114 FocusCycler* focus_cycler() { return focus_cycler_.get(); }
116 SystemTray* tray() { return tray_.get(); }
118 ShelfWidget* shelf_widget() {
119 return Launcher::ForPrimaryDisplay()->shelf_widget();
122 void InstallFocusCycleOnShelf() {
123 // Add the shelf.
124 shelf_widget()->SetFocusCycler(focus_cycler());
127 private:
128 scoped_ptr<FocusCycler> focus_cycler_;
129 scoped_ptr<SystemTray> tray_;
131 DISALLOW_COPY_AND_ASSIGN(FocusCyclerTest);
134 TEST_F(FocusCyclerTest, CycleFocusBrowserOnly) {
135 // Create a single test window.
136 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
137 wm::ActivateWindow(window0.get());
138 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
140 // Cycle the window
141 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
142 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
145 TEST_F(FocusCyclerTest, CycleFocusForward) {
146 ASSERT_TRUE(CreateTray());
148 InstallFocusCycleOnShelf();
150 // Create a single test window.
151 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
152 wm::ActivateWindow(window0.get());
153 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
155 // Cycle focus to the status area.
156 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
157 EXPECT_TRUE(tray()->GetWidget()->IsActive());
159 // Cycle focus to the shelf.
160 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
161 EXPECT_TRUE(shelf_widget()->IsActive());
163 // Cycle focus to the browser.
164 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
165 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
168 TEST_F(FocusCyclerTest, CycleFocusBackward) {
169 ASSERT_TRUE(CreateTray());
171 InstallFocusCycleOnShelf();
173 // Create a single test window.
174 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
175 wm::ActivateWindow(window0.get());
176 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
178 // Cycle focus to the shelf.
179 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
180 EXPECT_TRUE(shelf_widget()->IsActive());
182 // Cycle focus to the status area.
183 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
184 EXPECT_TRUE(tray()->GetWidget()->IsActive());
186 // Cycle focus to the browser.
187 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
188 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
191 TEST_F(FocusCyclerTest, CycleFocusForwardBackward) {
192 ASSERT_TRUE(CreateTray());
194 InstallFocusCycleOnShelf();
196 // Create a single test window.
197 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
198 wm::ActivateWindow(window0.get());
199 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
201 // Cycle focus to the shelf.
202 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
203 EXPECT_TRUE(shelf_widget()->IsActive());
205 // Cycle focus to the status area.
206 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
207 EXPECT_TRUE(tray()->GetWidget()->IsActive());
209 // Cycle focus to the browser.
210 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
211 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
213 // Cycle focus to the status area.
214 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
215 EXPECT_TRUE(tray()->GetWidget()->IsActive());
217 // Cycle focus to the shelf.
218 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
219 EXPECT_TRUE(shelf_widget()->IsActive());
221 // Cycle focus to the browser.
222 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
223 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
226 TEST_F(FocusCyclerTest, CycleFocusNoBrowser) {
227 ASSERT_TRUE(CreateTray());
229 InstallFocusCycleOnShelf();
231 // Add the shelf and focus it.
232 focus_cycler()->FocusWidget(shelf_widget());
234 // Cycle focus to the status area.
235 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
236 EXPECT_TRUE(tray()->GetWidget()->IsActive());
238 // Cycle focus to the shelf.
239 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
240 EXPECT_TRUE(shelf_widget()->IsActive());
242 // Cycle focus to the status area.
243 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
244 EXPECT_TRUE(tray()->GetWidget()->IsActive());
246 // Cycle focus to the shelf.
247 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
248 EXPECT_TRUE(shelf_widget()->IsActive());
250 // Cycle focus to the status area.
251 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
252 EXPECT_TRUE(tray()->GetWidget()->IsActive());
255 TEST_F(FocusCyclerTest, Shelf_CycleFocusForward) {
256 ASSERT_TRUE(CreateTray());
257 InstallFocusCycleOnShelf();
258 shelf_widget()->Hide();
260 // Create a single test window.
261 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
262 wm::ActivateWindow(window0.get());
263 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
265 // Cycle focus to the status area.
266 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
267 EXPECT_TRUE(tray()->GetWidget()->IsActive());
269 // Cycle focus to the browser.
270 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
271 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
274 TEST_F(FocusCyclerTest, Shelf_CycleFocusBackwardInvisible) {
275 ASSERT_TRUE(CreateTray());
276 InstallFocusCycleOnShelf();
277 shelf_widget()->Hide();
279 // Create a single test window.
280 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
281 wm::ActivateWindow(window0.get());
282 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
284 // Cycle focus to the status area.
285 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
286 EXPECT_TRUE(tray()->GetWidget()->IsActive());
288 // Cycle focus to the browser.
289 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
290 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
293 TEST_F(FocusCyclerTest, CycleFocusThroughWindowWithPanes) {
294 ASSERT_TRUE(CreateTray());
296 InstallFocusCycleOnShelf();
298 scoped_ptr<PanedWidgetDelegate> test_widget_delegate;
299 scoped_ptr<views::Widget> browser_widget(new views::Widget);
300 test_widget_delegate.reset(new PanedWidgetDelegate(browser_widget.get()));
301 views::Widget::InitParams widget_params(
302 views::Widget::InitParams::TYPE_WINDOW);
303 widget_params.context = CurrentContext();
304 widget_params.delegate = test_widget_delegate.get();
305 widget_params.ownership =
306 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
307 browser_widget->Init(widget_params);
308 browser_widget->Show();
310 aura::Window* browser_window = browser_widget->GetNativeView();
312 views::View* root_view = browser_widget->GetRootView();
314 views::AccessiblePaneView* pane1 = new views::AccessiblePaneView();
315 root_view->AddChildView(pane1);
317 views::View* view1 = new views::View;
318 view1->set_focusable(true);
319 pane1->AddChildView(view1);
321 views::View* view2 = new views::View;
322 view2->set_focusable(true);
323 pane1->AddChildView(view2);
325 views::AccessiblePaneView* pane2 = new views::AccessiblePaneView();
326 root_view->AddChildView(pane2);
328 views::View* view3 = new views::View;
329 view3->set_focusable(true);
330 pane2->AddChildView(view3);
332 views::View* view4 = new views::View;
333 view4->set_focusable(true);
334 pane2->AddChildView(view4);
336 std::vector<views::View*> panes;
337 panes.push_back(pane1);
338 panes.push_back(pane2);
340 test_widget_delegate->SetAccessiblePanes(panes);
342 views::FocusManager* focus_manager = browser_widget->GetFocusManager();
344 // Cycle focus to the status area.
345 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
346 EXPECT_TRUE(tray()->GetWidget()->IsActive());
348 // Cycle focus to the shelf.
349 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
350 EXPECT_TRUE(shelf_widget()->IsActive());
352 // Cycle focus to the first pane in the browser.
353 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
354 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
355 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
357 // Cycle focus to the second pane in the browser.
358 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
359 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
360 EXPECT_EQ(focus_manager->GetFocusedView(), view3);
362 // Cycle focus back to the status area.
363 focus_cycler()->RotateFocus(FocusCycler::FORWARD);
364 EXPECT_TRUE(tray()->GetWidget()->IsActive());
366 // Reverse direction - back to the second pane in the browser.
367 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
368 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
369 EXPECT_EQ(focus_manager->GetFocusedView(), view3);
371 // Back to the first pane in the browser.
372 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
373 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
374 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
376 // Back to the shelf.
377 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
378 EXPECT_TRUE(shelf_widget()->IsActive());
380 // Back to the status area.
381 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
382 EXPECT_TRUE(tray()->GetWidget()->IsActive());
384 // Pressing "Escape" while on the status area should
385 // deactivate it, and activate the browser window.
386 aura::Window* root = Shell::GetPrimaryRootWindow();
387 aura::test::EventGenerator event_generator(root, root);
388 event_generator.PressKey(ui::VKEY_ESCAPE, 0);
389 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
390 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
392 // Similarly, pressing "Escape" while on the shelf.
393 // should do the same thing.
394 focus_cycler()->RotateFocus(FocusCycler::BACKWARD);
395 EXPECT_TRUE(shelf_widget()->IsActive());
396 event_generator.PressKey(ui::VKEY_ESCAPE, 0);
397 EXPECT_TRUE(wm::IsActiveWindow(browser_window));
398 EXPECT_EQ(focus_manager->GetFocusedView(), view1);
401 } // namespace test
402 } // namespace ash