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.
5 #include "ash/shelf/shelf_tooltip_manager.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/shelf/shelf_layout_manager.h"
9 #include "ash/shelf/shelf_widget.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/test/shelf_test_api.h"
14 #include "ash/wm/window_util.h"
15 #include "base/strings/string16.h"
16 #include "base/time/time.h"
17 #include "ui/aura/window_event_dispatcher.h"
18 #include "ui/events/event.h"
19 #include "ui/events/event_constants.h"
20 #include "ui/events/event_handler.h"
21 #include "ui/events/keycodes/keyboard_codes.h"
22 #include "ui/events/test/events_test_utils.h"
23 #include "ui/views/widget/widget.h"
27 void SetEventTarget(ui::EventTarget
* target
,
29 ui::Event::DispatcherApi
dispatch_helper(event
);
30 dispatch_helper
.set_target(target
);
38 class ShelfTooltipManagerTest
: public AshTestBase
{
40 ShelfTooltipManagerTest() {}
41 virtual ~ShelfTooltipManagerTest() {}
43 virtual void SetUp() OVERRIDE
{
45 RootWindowController
* controller
= Shell::GetPrimaryRootWindowController();
46 tooltip_manager_
.reset(new ShelfTooltipManager(
47 controller
->GetShelfLayoutManager(),
48 ShelfTestAPI(controller
->shelf()->shelf()).shelf_view()));
51 virtual void TearDown() OVERRIDE
{
52 tooltip_manager_
.reset();
53 AshTestBase::TearDown();
58 tooltip_manager_
->ShowDelayed(dummy_anchor_
.get(), base::string16());
61 void ShowImmediately() {
63 tooltip_manager_
->ShowImmediately(dummy_anchor_
.get(), base::string16());
66 bool TooltipIsVisible() {
67 return tooltip_manager_
->IsVisible();
70 bool IsTimerRunning() {
71 return tooltip_manager_
->timer_
.get() != NULL
;
74 ui::EventHandler
* GetEventHandler() {
75 return tooltip_manager_
.get();
78 views::Widget
* GetTooltipWidget() {
79 return tooltip_manager_
->widget_
;
83 scoped_ptr
<views::Widget
> widget_
;
84 scoped_ptr
<views::View
> dummy_anchor_
;
85 scoped_ptr
<ShelfTooltipManager
> tooltip_manager_
;
89 dummy_anchor_
.reset(new views::View
);
91 widget_
.reset(new views::Widget
);
92 views::Widget::InitParams
params(
93 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS
);
94 params
.opacity
= views::Widget::InitParams::TRANSLUCENT_WINDOW
;
95 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
96 params
.parent
= Shell::GetContainer(Shell::GetPrimaryRootWindow(),
97 ash::kShellWindowId_ShelfContainer
);
99 widget_
->Init(params
);
100 widget_
->SetContentsView(dummy_anchor_
.get());
103 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipManagerTest
);
106 TEST_F(ShelfTooltipManagerTest
, ShowingBasics
) {
107 // ShowDelayed() should just start the timer instead of showing immediately.
109 EXPECT_FALSE(TooltipIsVisible());
110 EXPECT_TRUE(IsTimerRunning());
113 EXPECT_TRUE(TooltipIsVisible());
114 EXPECT_FALSE(IsTimerRunning());
117 TEST_F(ShelfTooltipManagerTest
, HideWhenShelfIsHidden
) {
119 ASSERT_TRUE(TooltipIsVisible());
121 // Create a full-screen window to hide the shelf.
122 scoped_ptr
<views::Widget
> widget(new views::Widget
);
123 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
124 params
.ownership
= views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
125 params
.context
= CurrentContext();
126 widget
->Init(params
);
127 widget
->SetFullscreen(true);
130 // Once the shelf is hidden, the tooltip should be invisible.
133 Shell::GetPrimaryRootWindowController()->
134 GetShelfLayoutManager()->visibility_state());
135 EXPECT_FALSE(TooltipIsVisible());
137 // Do not show the view if the shelf is hidden.
139 EXPECT_FALSE(TooltipIsVisible());
141 // ShowDelayed() doesn't even start the timer for the hidden shelf.
143 EXPECT_FALSE(IsTimerRunning());
146 TEST_F(ShelfTooltipManagerTest
, HideWhenShelfIsAutoHide
) {
147 // Create a visible window so auto-hide behavior is enforced.
148 views::Widget
* dummy
= new views::Widget
;
149 views::Widget::InitParams
params(views::Widget::InitParams::TYPE_WINDOW
);
150 params
.bounds
= gfx::Rect(0, 0, 200, 200);
151 params
.context
= CurrentContext();
156 ASSERT_TRUE(TooltipIsVisible());
158 ShelfLayoutManager
* shelf
=
159 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
160 shelf
->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
);
161 shelf
->UpdateAutoHideState();
162 ASSERT_EQ(SHELF_AUTO_HIDE_HIDDEN
, shelf
->auto_hide_state());
164 // Tooltip visibility change for auto hide may take time.
165 EXPECT_TRUE(TooltipIsVisible());
166 RunAllPendingInMessageLoop();
167 EXPECT_FALSE(TooltipIsVisible());
169 // Do not show the view if the shelf is hidden.
171 EXPECT_FALSE(TooltipIsVisible());
173 // ShowDelayed doesn't even run the timer for the hidden shelf.
175 EXPECT_FALSE(IsTimerRunning());
178 TEST_F(ShelfTooltipManagerTest
, ShouldHideForEvents
) {
180 ASSERT_TRUE(TooltipIsVisible());
182 aura::Window
* root_window
= Shell::GetInstance()->GetPrimaryRootWindow();
183 ui::EventHandler
* event_handler
= GetEventHandler();
185 // Should not hide for key events.
186 ui::KeyEvent
key_event(ui::ET_KEY_PRESSED
, ui::VKEY_A
, ui::EF_NONE
);
187 SetEventTarget(root_window
, &key_event
);
188 event_handler
->OnKeyEvent(&key_event
);
189 EXPECT_FALSE(key_event
.handled());
190 EXPECT_TRUE(TooltipIsVisible());
192 // Should hide for touch events.
193 ui::TouchEvent
touch_event(
194 ui::ET_TOUCH_PRESSED
, gfx::Point(), 0, base::TimeDelta());
195 SetEventTarget(root_window
, &touch_event
);
196 event_handler
->OnTouchEvent(&touch_event
);
197 EXPECT_FALSE(touch_event
.handled());
198 EXPECT_FALSE(TooltipIsVisible());
200 // Shouldn't hide if the touch happens on the tooltip.
202 views::Widget
* tooltip_widget
= GetTooltipWidget();
203 SetEventTarget(tooltip_widget
->GetNativeWindow(), &touch_event
);
204 event_handler
->OnTouchEvent(&touch_event
);
205 EXPECT_FALSE(touch_event
.handled());
206 EXPECT_TRUE(TooltipIsVisible());
208 // Should hide for gesture events.
209 ui::GestureEvent
gesture_event(
211 base::TimeDelta::FromMilliseconds(base::Time::Now().ToDoubleT() * 1000),
212 ui::GestureEventDetails(ui::ET_GESTURE_BEGIN
, 0.0f
, 0.0f
));
213 SetEventTarget(tooltip_widget
->GetNativeWindow(), &gesture_event
);
214 event_handler
->OnGestureEvent(&gesture_event
);
215 EXPECT_FALSE(gesture_event
.handled());
216 RunAllPendingInMessageLoop();
217 EXPECT_FALSE(TooltipIsVisible());
220 TEST_F(ShelfTooltipManagerTest
, HideForMouseMoveEvent
) {
222 ASSERT_TRUE(TooltipIsVisible());
224 aura::Window
* root_window
= Shell::GetInstance()->GetPrimaryRootWindow();
225 ui::EventHandler
* event_handler
= GetEventHandler();
227 gfx::Rect tooltip_rect
= GetTooltipWidget()->GetNativeWindow()->bounds();
228 ASSERT_FALSE(tooltip_rect
.IsEmpty());
230 // Shouldn't hide if the mouse is in the tooltip.
231 ui::MouseEvent
mouse_event(ui::ET_MOUSE_MOVED
, tooltip_rect
.CenterPoint(),
232 tooltip_rect
.CenterPoint(), ui::EF_NONE
,
234 ui::LocatedEventTestApi
test_api(&mouse_event
);
236 SetEventTarget(root_window
, &mouse_event
);
237 event_handler
->OnMouseEvent(&mouse_event
);
238 EXPECT_FALSE(mouse_event
.handled());
239 EXPECT_TRUE(TooltipIsVisible());
241 // Should hide if the mouse is out of the tooltip.
242 test_api
.set_location(tooltip_rect
.origin() + gfx::Vector2d(-1, -1));
243 event_handler
->OnMouseEvent(&mouse_event
);
244 EXPECT_FALSE(mouse_event
.handled());
245 RunAllPendingInMessageLoop();
246 EXPECT_FALSE(TooltipIsVisible());
249 // Checks that tooltip is hidden when mouse is pressed in anywhere.
250 TEST_F(ShelfTooltipManagerTest
, HideForMouseClickEvent
) {
252 ASSERT_TRUE(TooltipIsVisible());
254 aura::Window
* root_window
= Shell::GetInstance()->GetPrimaryRootWindow();
255 ui::EventHandler
* event_handler
= GetEventHandler();
257 gfx::Rect tooltip_rect
= GetTooltipWidget()->GetNativeWindow()->bounds();
258 ASSERT_FALSE(tooltip_rect
.IsEmpty());
260 // Should hide if the mouse is pressed in the tooltip.
261 ui::MouseEvent
mouse_event(ui::ET_MOUSE_PRESSED
, tooltip_rect
.CenterPoint(),
262 tooltip_rect
.CenterPoint(), ui::EF_NONE
,
265 SetEventTarget(root_window
, &mouse_event
);
266 event_handler
->OnMouseEvent(&mouse_event
);
267 EXPECT_FALSE(mouse_event
.handled());
268 RunAllPendingInMessageLoop();
269 EXPECT_FALSE(TooltipIsVisible());
271 // Should hide if the mouse is pressed outside of the tooltip.
273 ASSERT_TRUE(TooltipIsVisible());
275 ui::LocatedEventTestApi
test_api(&mouse_event
);
276 test_api
.set_location(tooltip_rect
.origin() + gfx::Vector2d(-1, -1));
278 SetEventTarget(root_window
, &mouse_event
);
279 event_handler
->OnMouseEvent(&mouse_event
);
280 EXPECT_FALSE(mouse_event
.handled());
281 RunAllPendingInMessageLoop();
282 EXPECT_FALSE(TooltipIsVisible());