1// Copyright 2013 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.
4
5#include "ash/shell.h"
6#include "ash/system/tray/system_tray.h"
7#include "base/command_line.h"
8#include "base/prefs/pref_service.h"
9#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
10#include "chrome/browser/profiles/profile.h"
11#include "chrome/browser/ui/browser.h"
12#include "chrome/browser/ui/tabs/tab_strip_model.h"
13#include "chrome/browser/ui/view_ids.h"
14#include "chrome/common/pref_names.h"
15#include "chrome/test/base/in_process_browser_test.h"
16#include "chrome/test/base/interactive_test_utils.h"
17#include "ui/aura/window_event_dispatcher.h"
18#include "ui/events/keycodes/keyboard_codes.h"
19#include "ui/gfx/native_widget_types.h"
20
21namespace chromeos {
22
23class StickyKeysBrowserTest : public InProcessBrowserTest {
24 protected:
25  StickyKeysBrowserTest() {}
26  virtual ~StickyKeysBrowserTest() {}
27
28  void EnableStickyKeys() {
29    AccessibilityManager::Get()->EnableStickyKeys(true);
30  }
31
32  void DisableStickyKeys() {
33    AccessibilityManager::Get()->EnableStickyKeys(false);
34  }
35
36  ash::SystemTray* GetSystemTray() {
37    return ash::Shell::GetInstance()->GetPrimarySystemTray();
38  }
39
40  void SendKeyPress(ui::KeyboardCode key) {
41    gfx::NativeWindow root_window =
42        ash::Shell::GetInstance()->GetPrimaryRootWindow();
43    ASSERT_TRUE(
44        ui_test_utils::SendKeyPressToWindowSync(root_window,
45                                                key,
46                                                false, // control
47                                                false, // shift
48                                                false, // alt
49                                                false)); // command
50  }
51
52  content::NotificationRegistrar registrar_;
53
54  DISALLOW_COPY_AND_ASSIGN(StickyKeysBrowserTest);
55};
56
57IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, OpenTrayMenu) {
58  EnableStickyKeys();
59
60  // Open system tray bubble with shortcut.
61  SendKeyPress(ui::VKEY_MENU); // alt key.
62  SendKeyPress(ui::VKEY_SHIFT);
63  SendKeyPress(ui::VKEY_S);
64  EXPECT_TRUE(GetSystemTray()->HasSystemBubble());
65
66  // Hide system bubble.
67  GetSystemTray()->CloseSystemBubble();
68  EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
69
70  // Pressing S again should not reopen the bubble.
71  SendKeyPress(ui::VKEY_S);
72  EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
73
74  // With sticky keys disabled, we will fail to perform the shortcut.
75  DisableStickyKeys();
76  SendKeyPress(ui::VKEY_MENU); // alt key.
77  SendKeyPress(ui::VKEY_SHIFT);
78  SendKeyPress(ui::VKEY_S);
79  EXPECT_FALSE(GetSystemTray()->HasSystemBubble());
80}
81
82IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, OpenNewTabs) {
83  // Lock the modifier key.
84  EnableStickyKeys();
85  SendKeyPress(ui::VKEY_CONTROL);
86  SendKeyPress(ui::VKEY_CONTROL);
87
88  // In the locked state, pressing 't' should open a new tab each time.
89  TabStripModel* tab_strip_model = browser()->tab_strip_model();
90  int tab_count = 1;
91  for (; tab_count < 5; ++tab_count) {
92    EXPECT_EQ(tab_count, tab_strip_model->count());
93    SendKeyPress(ui::VKEY_T);
94  }
95
96  // Unlock the modifier key and shortcut should no longer activate.
97  SendKeyPress(ui::VKEY_CONTROL);
98  SendKeyPress(ui::VKEY_T);
99  EXPECT_EQ(tab_count, tab_strip_model->count());
100
101  // Shortcut should not work after disabling sticky keys.
102  DisableStickyKeys();
103  SendKeyPress(ui::VKEY_CONTROL);
104  SendKeyPress(ui::VKEY_CONTROL);
105  SendKeyPress(ui::VKEY_T);
106  EXPECT_EQ(tab_count, tab_strip_model->count());
107}
108
109IN_PROC_BROWSER_TEST_F(StickyKeysBrowserTest, CtrlClickHomeButton) {
110  // Show home page button.
111  browser()->profile()->GetPrefs()->SetBoolean(prefs::kShowHomeButton, true);
112  TabStripModel* tab_strip_model = browser()->tab_strip_model();
113  int tab_count = 1;
114  EXPECT_EQ(tab_count, tab_strip_model->count());
115
116  // Test sticky keys with modified mouse click action.
117  EnableStickyKeys();
118  SendKeyPress(ui::VKEY_CONTROL);
119  ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
120  EXPECT_EQ(++tab_count, tab_strip_model->count());
121  ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
122  EXPECT_EQ(tab_count, tab_strip_model->count());
123
124  // Test locked modifier key with mouse click.
125  SendKeyPress(ui::VKEY_CONTROL);
126  SendKeyPress(ui::VKEY_CONTROL);
127  for (; tab_count < 5; ++tab_count) {
128    EXPECT_EQ(tab_count, tab_strip_model->count());
129    ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
130  }
131  SendKeyPress(ui::VKEY_CONTROL);
132  ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
133  EXPECT_EQ(tab_count, tab_strip_model->count());
134
135  // Test disabling sticky keys prevent modified mouse click.
136  DisableStickyKeys();
137  SendKeyPress(ui::VKEY_CONTROL);
138  ui_test_utils::ClickOnView(browser(), VIEW_ID_HOME_BUTTON);
139  EXPECT_EQ(tab_count, tab_strip_model->count());
140}
141
142}  // namespace chromeos
143