OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "ash/shelf/shelf_tooltip_manager.h" | 5 #include "ash/shelf/shelf_tooltip_manager.h" |
6 | 6 |
7 #include "ash/root_window_controller.h" | |
8 #include "ash/shelf/shelf_layout_manager.h" | 7 #include "ash/shelf/shelf_layout_manager.h" |
9 #include "ash/shelf/shelf_widget.h" | 8 #include "ash/shelf/shelf_widget.h" |
10 #include "ash/shell.h" | 9 #include "ash/shell.h" |
11 #include "ash/shell_window_ids.h" | 10 #include "ash/shell_window_ids.h" |
12 #include "ash/test/ash_test_base.h" | 11 #include "ash/test/ash_test_base.h" |
13 #include "ash/test/shelf_test_api.h" | 12 #include "ash/test/shelf_test_api.h" |
14 #include "ash/wm/window_util.h" | 13 #include "ash/test/shelf_view_test_api.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" | 14 #include "ui/events/event_constants.h" |
20 #include "ui/events/event_handler.h" | |
21 #include "ui/events/event_utils.h" | |
22 #include "ui/events/keycodes/keyboard_codes.h" | 15 #include "ui/events/keycodes/keyboard_codes.h" |
23 #include "ui/events/test/events_test_utils.h" | 16 #include "ui/events/test/event_generator.h" |
| 17 #include "ui/views/bubble/bubble_delegate.h" |
24 #include "ui/views/widget/widget.h" | 18 #include "ui/views/widget/widget.h" |
25 | 19 |
26 namespace { | |
27 | |
28 void SetEventTarget(ui::EventTarget* target, | |
29 ui::Event* event) { | |
30 ui::Event::DispatcherApi dispatch_helper(event); | |
31 dispatch_helper.set_target(target); | |
32 } | |
33 | |
34 } | |
35 | |
36 namespace ash { | 20 namespace ash { |
37 namespace test { | 21 namespace test { |
38 | 22 |
39 class ShelfTooltipManagerTest : public AshTestBase { | 23 class ShelfTooltipManagerTest : public AshTestBase { |
40 public: | 24 public: |
41 ShelfTooltipManagerTest() {} | 25 ShelfTooltipManagerTest() {} |
42 ~ShelfTooltipManagerTest() override {} | 26 ~ShelfTooltipManagerTest() override {} |
43 | 27 |
44 void SetUp() override { | 28 void SetUp() override { |
45 AshTestBase::SetUp(); | 29 AshTestBase::SetUp(); |
46 RootWindowController* controller = Shell::GetPrimaryRootWindowController(); | 30 shelf_ = Shelf::ForPrimaryDisplay(); |
47 tooltip_manager_.reset(new ShelfTooltipManager( | 31 ShelfView* shelf_view = test::ShelfTestAPI(shelf_).shelf_view(); |
48 controller->GetShelfLayoutManager(), | 32 tooltip_manager_ = test::ShelfViewTestAPI(shelf_view).tooltip_manager(); |
49 ShelfTestAPI(controller->shelf()->shelf()).shelf_view())); | |
50 } | |
51 | |
52 void TearDown() override { | |
53 tooltip_manager_.reset(); | |
54 AshTestBase::TearDown(); | |
55 } | 33 } |
56 | 34 |
57 void ShowDelayed() { | 35 void ShowDelayed() { |
58 CreateWidget(); | 36 CreateWidget(); |
59 tooltip_manager_->ShowDelayed(dummy_anchor_.get(), base::string16()); | 37 tooltip_manager_->ShowTooltipWithDelay(dummy_anchor_.get()); |
60 } | 38 } |
61 | 39 |
62 void ShowImmediately() { | 40 void ShowImmediately() { |
63 CreateWidget(); | 41 CreateWidget(); |
64 tooltip_manager_->ShowImmediately(dummy_anchor_.get(), base::string16()); | 42 tooltip_manager_->ShowTooltip(dummy_anchor_.get()); |
65 } | 43 } |
66 | 44 |
67 bool TooltipIsVisible() { | 45 bool TooltipIsVisible() { return tooltip_manager_->IsVisible(); } |
68 return tooltip_manager_->IsVisible(); | 46 bool IsTimerRunning() { return tooltip_manager_->timer_.IsRunning(); } |
69 } | |
70 | 47 |
71 bool IsTimerRunning() { | 48 aura::Window* GetTooltipWindow() { |
72 return tooltip_manager_->timer_.get() != NULL; | 49 return tooltip_manager_->bubble_->GetWidget()->GetNativeWindow(); |
73 } | |
74 | |
75 ui::EventHandler* GetEventHandler() { | |
76 return tooltip_manager_.get(); | |
77 } | |
78 | |
79 views::Widget* GetTooltipWidget() { | |
80 return tooltip_manager_->widget_; | |
81 } | 50 } |
82 | 51 |
83 protected: | 52 protected: |
84 scoped_ptr<views::Widget> widget_; | 53 scoped_ptr<views::Widget> widget_; |
85 scoped_ptr<views::View> dummy_anchor_; | 54 scoped_ptr<views::View> dummy_anchor_; |
86 scoped_ptr<ShelfTooltipManager> tooltip_manager_; | 55 |
| 56 Shelf* shelf_; |
| 57 ShelfTooltipManager* tooltip_manager_; |
87 | 58 |
88 private: | 59 private: |
89 void CreateWidget() { | 60 void CreateWidget() { |
90 dummy_anchor_.reset(new views::View); | 61 dummy_anchor_.reset(new views::View); |
91 | |
92 widget_.reset(new views::Widget); | 62 widget_.reset(new views::Widget); |
93 views::Widget::InitParams params( | 63 views::Widget::InitParams params( |
94 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | 64 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); |
95 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 65 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
96 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 66 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
97 params.parent = Shell::GetContainer(Shell::GetPrimaryRootWindow(), | 67 params.parent = Shell::GetContainer(Shell::GetPrimaryRootWindow(), |
98 ash::kShellWindowId_ShelfContainer); | 68 ash::kShellWindowId_ShelfContainer); |
99 | |
100 widget_->Init(params); | 69 widget_->Init(params); |
101 widget_->SetContentsView(dummy_anchor_.get()); | 70 widget_->SetContentsView(dummy_anchor_.get()); |
102 } | 71 } |
103 | 72 |
104 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipManagerTest); | 73 DISALLOW_COPY_AND_ASSIGN(ShelfTooltipManagerTest); |
105 }; | 74 }; |
106 | 75 |
107 TEST_F(ShelfTooltipManagerTest, ShowingBasics) { | 76 TEST_F(ShelfTooltipManagerTest, ShowingBasics) { |
108 // ShowDelayed() should just start the timer instead of showing immediately. | 77 // ShowDelayed() should just start the timer instead of showing immediately. |
109 ShowDelayed(); | 78 ShowDelayed(); |
(...skipping 12 matching lines...) Expand all Loading... |
122 // Create a full-screen window to hide the shelf. | 91 // Create a full-screen window to hide the shelf. |
123 scoped_ptr<views::Widget> widget(new views::Widget); | 92 scoped_ptr<views::Widget> widget(new views::Widget); |
124 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | 93 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); |
125 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 94 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
126 params.context = CurrentContext(); | 95 params.context = CurrentContext(); |
127 widget->Init(params); | 96 widget->Init(params); |
128 widget->SetFullscreen(true); | 97 widget->SetFullscreen(true); |
129 widget->Show(); | 98 widget->Show(); |
130 | 99 |
131 // Once the shelf is hidden, the tooltip should be invisible. | 100 // Once the shelf is hidden, the tooltip should be invisible. |
132 ASSERT_EQ( | 101 ASSERT_EQ(SHELF_HIDDEN, shelf_->shelf_layout_manager()->visibility_state()); |
133 SHELF_HIDDEN, | |
134 Shell::GetPrimaryRootWindowController()-> | |
135 GetShelfLayoutManager()->visibility_state()); | |
136 EXPECT_FALSE(TooltipIsVisible()); | 102 EXPECT_FALSE(TooltipIsVisible()); |
137 | 103 |
138 // Do not show the view if the shelf is hidden. | 104 // Do not show the view if the shelf is hidden. |
139 ShowImmediately(); | 105 ShowImmediately(); |
140 EXPECT_FALSE(TooltipIsVisible()); | 106 EXPECT_FALSE(TooltipIsVisible()); |
141 | 107 |
142 // ShowDelayed() doesn't even start the timer for the hidden shelf. | 108 // ShowDelayed() doesn't even start the timer for the hidden shelf. |
143 ShowDelayed(); | 109 ShowDelayed(); |
144 EXPECT_FALSE(IsTimerRunning()); | 110 EXPECT_FALSE(IsTimerRunning()); |
145 } | 111 } |
146 | 112 |
147 TEST_F(ShelfTooltipManagerTest, HideWhenShelfIsAutoHide) { | 113 TEST_F(ShelfTooltipManagerTest, HideWhenShelfIsAutoHide) { |
148 // Create a visible window so auto-hide behavior is enforced. | 114 // Create a visible window so auto-hide behavior is enforced. |
149 views::Widget* dummy = new views::Widget; | 115 views::Widget* dummy = new views::Widget; |
150 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); | 116 views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); |
151 params.bounds = gfx::Rect(0, 0, 200, 200); | 117 params.bounds = gfx::Rect(0, 0, 200, 200); |
152 params.context = CurrentContext(); | 118 params.context = CurrentContext(); |
153 dummy->Init(params); | 119 dummy->Init(params); |
154 dummy->Show(); | 120 dummy->Show(); |
155 | 121 |
156 ShowImmediately(); | 122 ShowImmediately(); |
157 ASSERT_TRUE(TooltipIsVisible()); | 123 ASSERT_TRUE(TooltipIsVisible()); |
158 | 124 |
159 ShelfLayoutManager* shelf = | 125 ShelfLayoutManager* shelf_layout_manager = shelf_->shelf_layout_manager(); |
160 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); | 126 shelf_layout_manager->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); |
161 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); | 127 shelf_layout_manager->UpdateAutoHideState(); |
162 shelf->UpdateAutoHideState(); | 128 ASSERT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_layout_manager->auto_hide_state()); |
163 ASSERT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->auto_hide_state()); | |
164 | 129 |
165 // Tooltip visibility change for auto hide may take time. | 130 // Tooltip visibility change for auto hide may take time. |
166 EXPECT_TRUE(TooltipIsVisible()); | 131 EXPECT_TRUE(TooltipIsVisible()); |
167 RunAllPendingInMessageLoop(); | 132 RunAllPendingInMessageLoop(); |
168 EXPECT_FALSE(TooltipIsVisible()); | 133 EXPECT_FALSE(TooltipIsVisible()); |
169 | 134 |
170 // Do not show the view if the shelf is hidden. | 135 // Do not show the view if the shelf is hidden. |
171 ShowImmediately(); | 136 ShowImmediately(); |
172 EXPECT_FALSE(TooltipIsVisible()); | 137 EXPECT_FALSE(TooltipIsVisible()); |
173 | 138 |
174 // ShowDelayed doesn't even run the timer for the hidden shelf. | 139 // ShowDelayed doesn't even run the timer for the hidden shelf. |
175 ShowDelayed(); | 140 ShowDelayed(); |
176 EXPECT_FALSE(IsTimerRunning()); | 141 EXPECT_FALSE(IsTimerRunning()); |
177 } | 142 } |
178 | 143 |
179 TEST_F(ShelfTooltipManagerTest, ShouldHideForEvents) { | 144 TEST_F(ShelfTooltipManagerTest, HideForEvents) { |
| 145 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); |
| 146 gfx::Rect shelf_bounds = shelf_->shelf_widget()->GetNativeWindow()->bounds(); |
| 147 |
| 148 // Should hide if the mouse exits the shelf area. |
| 149 ShowImmediately(); |
| 150 ASSERT_TRUE(TooltipIsVisible()); |
| 151 generator.MoveMouseTo(shelf_bounds.CenterPoint()); |
| 152 generator.SendMouseExit(); |
| 153 EXPECT_FALSE(TooltipIsVisible()); |
| 154 |
| 155 // Should hide if the mouse is pressed in the shelf area. |
| 156 ShowImmediately(); |
| 157 ASSERT_TRUE(TooltipIsVisible()); |
| 158 generator.MoveMouseTo(shelf_bounds.CenterPoint()); |
| 159 generator.PressLeftButton(); |
| 160 EXPECT_FALSE(TooltipIsVisible()); |
| 161 |
| 162 // Should hide for touch events in the shelf. |
| 163 ShowImmediately(); |
| 164 ASSERT_TRUE(TooltipIsVisible()); |
| 165 generator.set_current_location(shelf_bounds.CenterPoint()); |
| 166 generator.PressTouch(); |
| 167 EXPECT_FALSE(TooltipIsVisible()); |
| 168 |
| 169 // Should hide for gesture events in the shelf. |
| 170 ShowImmediately(); |
| 171 ASSERT_TRUE(TooltipIsVisible()); |
| 172 generator.GestureTapDownAndUp(shelf_bounds.CenterPoint()); |
| 173 EXPECT_FALSE(TooltipIsVisible()); |
| 174 } |
| 175 |
| 176 // TODO(msw): Hiding for touch and gesture events outside the shelf is broken. |
| 177 TEST_F(ShelfTooltipManagerTest, HideForEventsBroken) { |
| 178 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); |
| 179 |
180 ShowImmediately(); | 180 ShowImmediately(); |
181 ASSERT_TRUE(TooltipIsVisible()); | 181 ASSERT_TRUE(TooltipIsVisible()); |
182 | 182 |
183 aura::Window* root_window = Shell::GetInstance()->GetPrimaryRootWindow(); | 183 generator.set_current_location(gfx::Point()); |
184 ui::EventHandler* event_handler = GetEventHandler(); | 184 generator.PressTouch(); |
185 | |
186 // Should not hide for key events. | |
187 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); | |
188 SetEventTarget(root_window, &key_event); | |
189 event_handler->OnKeyEvent(&key_event); | |
190 EXPECT_FALSE(key_event.handled()); | |
191 EXPECT_TRUE(TooltipIsVisible()); | 185 EXPECT_TRUE(TooltipIsVisible()); |
192 | 186 |
193 // Should hide for touch events. | 187 generator.GestureTapDownAndUp(gfx::Point()); |
194 ui::TouchEvent touch_event( | |
195 ui::ET_TOUCH_PRESSED, gfx::Point(), 0, base::TimeDelta()); | |
196 SetEventTarget(root_window, &touch_event); | |
197 event_handler->OnTouchEvent(&touch_event); | |
198 EXPECT_FALSE(touch_event.handled()); | |
199 EXPECT_FALSE(TooltipIsVisible()); | |
200 | |
201 // Shouldn't hide if the touch happens on the tooltip. | |
202 ShowImmediately(); | |
203 views::Widget* tooltip_widget = GetTooltipWidget(); | |
204 SetEventTarget(tooltip_widget->GetNativeWindow(), &touch_event); | |
205 event_handler->OnTouchEvent(&touch_event); | |
206 EXPECT_FALSE(touch_event.handled()); | |
207 EXPECT_TRUE(TooltipIsVisible()); | 188 EXPECT_TRUE(TooltipIsVisible()); |
208 | |
209 // Should hide for gesture events. | |
210 ui::GestureEvent gesture_event( | |
211 0, | |
212 0, | |
213 ui::EF_NONE, | |
214 base::TimeDelta::FromMilliseconds(base::Time::Now().ToDoubleT() * 1000), | |
215 ui::GestureEventDetails(ui::ET_GESTURE_BEGIN)); | |
216 SetEventTarget(tooltip_widget->GetNativeWindow(), &gesture_event); | |
217 event_handler->OnGestureEvent(&gesture_event); | |
218 EXPECT_FALSE(gesture_event.handled()); | |
219 RunAllPendingInMessageLoop(); | |
220 EXPECT_FALSE(TooltipIsVisible()); | |
221 } | 189 } |
222 | 190 |
223 TEST_F(ShelfTooltipManagerTest, HideForMouseMoveEvent) { | 191 TEST_F(ShelfTooltipManagerTest, DoNotHideForEvents) { |
| 192 ui::test::EventGenerator generator(ash::Shell::GetPrimaryRootWindow()); |
| 193 |
224 ShowImmediately(); | 194 ShowImmediately(); |
225 ASSERT_TRUE(TooltipIsVisible()); | 195 ASSERT_TRUE(TooltipIsVisible()); |
226 | 196 |
227 aura::Window* root_window = Shell::GetInstance()->GetPrimaryRootWindow(); | 197 // Should not hide for key events. |
228 ui::EventHandler* event_handler = GetEventHandler(); | 198 generator.PressKey(ui::VKEY_A, ui::EF_NONE); |
229 | |
230 gfx::Rect tooltip_rect = GetTooltipWidget()->GetNativeWindow()->bounds(); | |
231 ASSERT_FALSE(tooltip_rect.IsEmpty()); | |
232 | |
233 // Shouldn't hide if the mouse is in the tooltip. | |
234 ui::MouseEvent mouse_event(ui::ET_MOUSE_MOVED, tooltip_rect.CenterPoint(), | |
235 tooltip_rect.CenterPoint(), ui::EventTimeForNow(), | |
236 ui::EF_NONE, ui::EF_NONE); | |
237 ui::LocatedEventTestApi test_api(&mouse_event); | |
238 | |
239 SetEventTarget(root_window, &mouse_event); | |
240 event_handler->OnMouseEvent(&mouse_event); | |
241 EXPECT_FALSE(mouse_event.handled()); | |
242 EXPECT_TRUE(TooltipIsVisible()); | 199 EXPECT_TRUE(TooltipIsVisible()); |
243 | 200 |
244 // Should hide if the mouse is out of the tooltip. | 201 // Should not hide for touch events on the tooltip. |
245 test_api.set_location(tooltip_rect.origin() + gfx::Vector2d(-1, -1)); | 202 generator.set_current_location(GetTooltipWindow()->bounds().CenterPoint()); |
246 event_handler->OnMouseEvent(&mouse_event); | 203 generator.PressTouch(); |
247 EXPECT_FALSE(mouse_event.handled()); | 204 EXPECT_TRUE(TooltipIsVisible()); |
248 RunAllPendingInMessageLoop(); | |
249 EXPECT_FALSE(TooltipIsVisible()); | |
250 } | |
251 | |
252 // Checks that tooltip is hidden when mouse is pressed in anywhere. | |
253 TEST_F(ShelfTooltipManagerTest, HideForMouseClickEvent) { | |
254 ShowImmediately(); | |
255 ASSERT_TRUE(TooltipIsVisible()); | |
256 | |
257 aura::Window* root_window = Shell::GetInstance()->GetPrimaryRootWindow(); | |
258 ui::EventHandler* event_handler = GetEventHandler(); | |
259 | |
260 gfx::Rect tooltip_rect = GetTooltipWidget()->GetNativeWindow()->bounds(); | |
261 ASSERT_FALSE(tooltip_rect.IsEmpty()); | |
262 | |
263 // Should hide if the mouse is pressed in the tooltip. | |
264 ui::MouseEvent mouse_event(ui::ET_MOUSE_PRESSED, tooltip_rect.CenterPoint(), | |
265 tooltip_rect.CenterPoint(), ui::EventTimeForNow(), | |
266 ui::EF_NONE, ui::EF_NONE); | |
267 | |
268 SetEventTarget(root_window, &mouse_event); | |
269 event_handler->OnMouseEvent(&mouse_event); | |
270 EXPECT_FALSE(mouse_event.handled()); | |
271 RunAllPendingInMessageLoop(); | |
272 EXPECT_FALSE(TooltipIsVisible()); | |
273 | |
274 // Should hide if the mouse is pressed outside of the tooltip. | |
275 ShowImmediately(); | |
276 ASSERT_TRUE(TooltipIsVisible()); | |
277 | |
278 ui::LocatedEventTestApi test_api(&mouse_event); | |
279 test_api.set_location(tooltip_rect.origin() + gfx::Vector2d(-1, -1)); | |
280 | |
281 SetEventTarget(root_window, &mouse_event); | |
282 event_handler->OnMouseEvent(&mouse_event); | |
283 EXPECT_FALSE(mouse_event.handled()); | |
284 RunAllPendingInMessageLoop(); | |
285 EXPECT_FALSE(TooltipIsVisible()); | |
286 } | 205 } |
287 | 206 |
288 } // namespace test | 207 } // namespace test |
289 } // namespace ash | 208 } // namespace ash |
OLD | NEW |